62
SUB CODE:IT0407 SUB NAME:INTEGRATIVE PROGRAMMING & TECHNOLOGIES SEM : VII 1 12/26/2012 N.J.Subashini Assistant Professor,(Sr. G) SRM University, Kattankulathur

SUB CODE:IT0407 SUB NAME:INTEGRATIVE · PDF fileSUB NAME:INTEGRATIVE PROGRAMMING & TECHNOLOGIES. ... ÆNMI has design characteristics that make it unsuitable ... are inside a Java

Embed Size (px)

Citation preview

SUB CODE:IT0407 

SUB NAME:INTEGRATIVE PROGRAMMING & TECHNOLOGIES

SEM : VII 

112/26/2012

N.J.Subashini

Assistant Professor,(Sr. G)

SRM University, Kattankulathur

212/26/2012

UNIT ‐ I

312/26/2012

UNIT 1 LANGUAGE INTEROPERABILITY INJAVA 9

Using non-Java code: The Java Native Interface- Calling a native method -Implementing your DLL- Accessing JNI functions - Passing and usingJava objects - JNI and Java exceptions-JNI andthreading

412/26/2012

Introduction

512/26/2012

to access the non java codes different vendors provides different solutions

Java 1.1 has the Java Native Interface (JNI)Netscape has proposed its Java Runtime InterfaceMicrosoft offers J/Direct, Raw Native Interface

(RNI), and Java/COM integration.Another Solution is CORBA((Common Object

Request Broker Architecture), an integration technology developed by the OMG (Object Management Group) –interoperable with objects – no language specific –provides common communication bus and services called ORB(Object Request Broker)

612/26/2012

Java Native Interface

712/26/2012

JNI is a fairly rich programming interface that allow to call native methods from a Java application.

It was added in Java 1.1, maintaining a certain degree of compatibility with its Java 1.0 equivalent, the native method interface (NMI).

NMI has design characteristics that make it unsuitable for adoption in all virtual machines.

For this reason, future versions of the language might no longer support NMI.

812/26/2012

JNI is designed to interface with native methods written only in C or C++.

Using JNI, native methods can:Create, inspect, and update Java objects (including

arrays and Strings)Call Java methodsCatch and throw exceptionsLoad classes and obtain class informationPerform runtime type checking

Thus, virtually everything which can be done with classes and objects in ordinary Java can also be done in native methods.

912/26/2012

Steps for creating a JNI Program:-1. Create a java file with a ‘native ‘ methods2. Create header file for the java file3. Create C file using the header file

generated for the java file, which have the native method structure

4. Create .dll file5. Execute the program

1012/26/2012

1112/26/2012

Create a java file with a ‘native ‘ methods:-Create a new project called as JniDemo, don’t remove the check boxes in ita project with a subpackage called jnidemo and a class called Main will be opened.now include the following code in it

1212/26/2012

package jnidemo;

public class Main {

private native static void nativePrint();public native static int intMethod(int n);

public static void main(String[] args) {nativePrint();System.out.println("Sum=="+ intMethod(10));

}}

Compile and build

1312/26/2012

Create header file for the java fileTo create the .h file for the java file use the following commandE:\Programs\Jnidemo\src\jnidemo>"C:\Program Files\Java\jdk1.6.0_07\bin\javah.exe" -o HelloWorldNaive.h -jni -classpath ..\..\build\classes jnidemo.MainA HelloWorldNative.h C header file is generated. It is required to provide correct function declaration for the native implementation of the nativePrint() method.

1412/26/2012

Header file generated will contain the native method definition that to be implemented in C/C++ codeCopy the definitions of the following format

JNIEXPORT void JNICALL Java_ajnidemo_Main_nativePrint(JNIEnv *, jclass);

JNIEXPORT jint JNICALL Java_ajnidemo_Main_intMethod(JNIEnv *, jclass, jint);

JNIEXPORT and JNICALL are macros that expand to match platform-specific directives, it is also used to specify the calling and linkage convention of both JNI functions and native method implementations.

1512/26/2012

The first argument, of type JNIEnv, contains all the hooks that allow to call back into the JVM.

The second argument has a different meaning depending on the type of method. •For non-static methods (also called instance methods), the second argument is the equivalent of the “this” pointer in C++ and similar to “this” in Java: it’s a reference to the object that called the native method.•For static methods, it’s a reference to the Class object where the method is implemented.

The remaining arguments represent the Java objects passed into the native method call. Primitives are also passed in this way, but they come in by value.

1612/26/2012

The JNIEnv argumentJNI functions are those that the programmer uses to interact with the JVM from inside

a native method. Every JNI native method receives a special argument as its first parameter: the

JNIEnv argument, which is a pointer to a specialJNI data structure of type JNIEnv_.

One element of the JNI data structure is a pointer to anarray generated by the JVM; each element of this array is a pointer to a JNI function.

The JNI functions can be called from the native method by dereferencing these pointers

Every JVM provides its own implementation of the JNI functions

1712/26/2012

1812/26/2012

JNI Primitive Types

1912/26/2012

JNI Reference Types

2012/26/2012

Through the JNIEnv argument, the programmer has access to a large set of functions. These functions can be grouped into the following categories:

Obtaining version informationPerforming class and object operationsHandling global and local references to Java

objectsAccessing instance fields and static fieldsCalling instance methods and static methodsPerforming string and array operationsGenerating and handling Java exceptions

2112/26/2012

In the jni.h header file, we can see that inside the #ifdef __cplusplus preprocessor conditional, the JNIEnv_ structure is defined as a class when compiled by a C++ compiler. This class contains a number of inline functions that let you access the JNIfunctions with an easy and familiar syntax

Example:In C(*jEnv) ReleaseStringUTFChars(jEnv,jMsg, msg);

In C++jEnv ReleaseStringUTFChars(jMsg, msg);

2212/26/2012

About Cygwin:Cygwin is:

a collection of tools which provide a Linux look and feel environment for Windows.a DLL (cygwin1.dll) which acts as a Linux API layer providing substantial Linux API

functionality.

Cygwin is not:a way to run native Linux apps on Windows. You must rebuild your application from

source if you want it to run on Windows.a way to magically make native Windows apps aware of UNIX® functionality like

signals, ptys, etc. Again, you need to build your apps from source if you want to take advantage of Cygwin functionality.

2312/26/2012

Before creating the C file just download and install CYGWIN to enable C/C++ package in netbeans IDE.

Steps for doing it1. Download and run the Cygwin installer

from http://www.cygwin.com/setup.exe.2. At the Choose Installation Type page, select Install

From Internet, and click Next.3. At the Choose Installation Directory page, define the

settings appropriate for the system, then click Next.4. At the Select Local Package Directory page, define

the directory which Cygwin installer will use as its cache directory, and click Next.

2412/26/2012

5. At the Select Connection Type page, choose the type of Internet connection you have, and click Next.

6. At the Choose Download Site(s) page, select a mirror which is closest to your location, and click Next.

7. At the Select Packages page, select at least these packages: gcc-core, gcc-g++, gdb, and make.

2512/26/2012

Create a C programOpen a C/C++ application and a C Main file in to it (JniCApp project name and MainC

file).press Ctrl 2 and select the Jnidemo project and select src.You can find the .h file in it. Drag and drop it the JniCApp project which will be

included in the nbproject folderremove the main method in it and paste the methods that is been copied from the

header fileinclude 2 header files in the c file

1. #include “HelloWorldNative.h”2. #include <jni.h>

Now give the method body for the methods pasted from header file as follows

2612/26/2012

JNIEXPORT void JNICALL Java_ajnidemo_Main_nativePrint(JNIEnv *env, jobject obj)

{printf("\nHello World Native ");

}JNIEXPORT jint JNICALL Java_ajnidemo_Main_intMethod(JNIEnv *env, jobject obj, jint num)

{return num+num;

}

Save, Right click and build the project

2712/26/2012

To enable jni.h header file do the following step1. Right-click the project node and choose Properties from the context menu.2. Select C Complier from categories click include directories from it I the next

dialog box click Add button, from the select directory dialog select the following paths and click ok

C:/Program Files/Java/jdk1.6.0_07/include C:/Program Files/Java/jdk1.6.0_07/include/win32

3. Now click the Additional option and type the following-mno-cygwin -Wl,--add-stdcall-alias -shared -m32

4. Select Linker from categories and type the following in outputdist/HelloWorldNative.dll which will create the .dll file in the ‘dist’ folder of JniCApp project

2812/26/2012

The -mno-cygwin option, enables building DLLs that have no dependencies on Cygwin own libraries and thus can be executed on machines which do not have Cygwin installed.

The -Wl,--add-stdcall-alias passes the --add-stdcall-alias option to the linker; without it, the resulting application would fail with the UnsatisfiedLinkError.

The -shared option tells the compiler to generate a DLL ( not an executable file).

-m32 tells the compiler to create a 32-bit binary. On 64-bit systems the compiled binaries are 64-bit by default,which causes a lot of problems with 32-bit JDKs.

2912/26/2012

Now include the .dll file in the java file as shown belowstatic {

System.load ("E:\\Programs\\AJNICApp\\dist\\HelloWorldNative.dll");} Execute your java file

3012/26/2012

Accessing Java Strings:-Java Strings are in Unicode formatif the user want to pass it to a non-Unicode function (printf( ), for example), user must

first convert it into ASCII characters with the JNI function GetStringUTFChars( ). This function takes a Java String and converts it to UTF-8 characters.

const char *str = (*env)->GetStringUTFChars(env,string,0)

to convert back to unicode format string(*env)->ReleaseStringUTFChars(env,string,str);

3112/26/2012

Passing and using Java objects

3212/26/2012

In the above program int value is passed as an argument. In Native methods we can also pass java object as an arguments follows

class MyJavaClass{public void divByTwo() {

aValue /= 2.0f;System.out.printn(aValue);

}public flaot aValue;}

3312/26/2012

public class UseObjects {public static void main(String [] args) {UseObjects app = new UseObjects();MyJavaClass anObj = new MyJavaClass();anObj.aValue = 2;app.changeObject(anObj);System.out.println("Java: " + anObj.aValue);}private native void changeObject(MyJavaClass obj);static {System.loadLibrary("UseObjImpl");}}

3412/26/2012

JNI Method is of the format as follows:-

JNIEXPORT void JNICALL Java_UseObjects_changeObject (JNIEnv * env, jobject jThis, jobject obj) { //body}

3512/26/2012

JNI and Java exceptions:-With JNI, Java exceptions can be thrown, caught, printed, and rethrown just as they

are inside a Java program. But it’s up to the programmer to call dedicated JNI functions to deal with exceptions.

Here are the JNI functions for exception handling:1. Throw( ) Throws an existing exception object. Used in native methods to rethrow

an exception.2. ThrowNew( ) Generates a new exception object and throws it.3. ExceptionOccurred( ) Determines if an exception was thrown and not yet

cleared.

3612/26/2012

4. ExceptionDescribe( ) Prints an exception and the stack trace.5. ExceptionClear( ) Clears a pending exception.6. FatalError( ) Raises a fatal error. Does not return

3712/26/2012

Example:-JAVA CODE:-class CatchThrow {private native void doit() throws IllegalArgumentException;private void callback() throws NullPointerException {throw new NullPointerException("CatchThrow.callback"); }public static void main(String args[]) {CatchThrow c = new CatchThrow();try { c.doit(); c.callback();} catch (Exception e) { System.out.println("In Java:\n\t" + e); }}static { System.loadLibrary("CatchThrow"); }}

3812/26/2012

PART OF C CODE:-JNIEXPORT void JNICALLJava_CatchThrow_doit(JNIEnv *env, jobject obj){- - -exc = (*env)->ExceptionOccurred(env);if (exc) {- - -(*env)->ExceptionDescribe(env);(*env)->ExceptionClear(env);- - -}(*env)->ThrowNew(env, newExcCls, "thrown from C code");}

3912/26/2012

JNI and threading

4012/26/2012

Synchronization

4112/26/2012

When two or more threads need access to a shared resource, they need some way to ensure that the resource will be used by only one thread at a time.

The process by which this is achieved is called synchronization.

Java provides unique, language-level support for it.Key to synchronization is the concept of the monitor

(also called a semaphore). A monitor is an object that is used as a mutually

exclusive lock, or mutex.

4212/26/2012

Only one thread can own a monitor at a given time. When a thread acquires a lock, it is said to have entered the monitor. All other threads attempting to enter the locked monitor will be

suspended until the first thread exits the monitor. These other threads are said to be waiting for the monitor. A thread that owns a monitor can reenter the same monitor if it so desires.synchronization can be done in two ways using synchronized keyword

1. Applying for a method (synchronized Method)2. Applying for a Statement (synchronized Block)

4312/26/2012

4412/26/2012

Using Synchronized Methods

4512/26/2012

Example: Without Using Synchronization

Here is the output produced by this program:Hello[Synchronized[World]]]

4612/26/2012

Example: With Synchronization

OUTPUT:‐[Hello][World][Synchronized]

4712/26/2012

The synchronized Statement

4812/26/2012

Example: With Synchronization statement

Output:‐

[Hello][World][Synchronized]

4912/26/2012

JNI and ThreadsThe Java virtual machine supports multiple threads of control concurrently executing

in the same address space. This concurrency introduces a degree of complexity that user do not have in a single-

threaded environment. Multiple threads may access the same objects, the same file descriptors, the same

shared resources--at the same time.Constraints

There are certain constraints that user must keep in mind when writing native methods that are to run in a multithreaded environment.

By understanding and programming within these constraints, native methods will execute safely no matter how many threads simultaneously execute a given native method.

5012/26/2012

For example:A JNIEnv pointer is only valid in the thread associated with it, user should not pass

this pointer from one thread to another, or cache and use it in multiple threads. The JVM passes a native method the same JNIEnv pointer in consecutive invocations

from the same thread, but passes different JNIEnv pointers when invoking that native method from different threads.

Local references are valid only in the thread that created them. User should not pass local references from one thread to another. User should always convert local references to global references whenever there is a possibility that multiple threads may use the same reference.

5112/26/2012

Monitor Entry and Exit

Monitors are the primitive synchronization mechanism on the Java platform. Each object can be dynamically associated with a monitor. The JNI allows user to synchronize using these monitors, thus implementing the

functionality equivalent to a synchronized block in the Java programming language:

synchronized (obj) {

... // synchronized block}

5212/26/2012

The Java virtual machine guarantees that a thread acquires the monitor associated with the object obj before it executes any statements in the block.

This ensures that there can be at most one thread that holds the monitor and executes inside the synchronized block at any given time.

A thread blocks when it waits for another thread to exit a monitor.Native code can use JNI functions to perform equivalent synchronization on JNI

references. User can use the MonitorEnter function to enter the monitor and the MonitorExit

function to exit the monitor:

5312/26/2012

if ((*env)->MonitorEnter(env, obj) != JNI_OK) {

... /* error handling */}... /* synchronized block */if ((*env)->MonitorExit(env, obj) != JNI_OK){

... /* error handling */};

5412/26/2012

Executing the code above, a thread must first enter the monitor associated with objbefore executing any code inside the synchronized block.

The Monitor-Enter operation takes a jobject as an argument and blocks if another thread has already entered the monitor associated with the jobject.

Calling MonitorExit when the current thread does not own the monitor results in an error and causes an IllegalMonitorStateException to be raised.

The above code contains a matched pair of MonitorEnter and MonitorExit calls, yet user still need to check for possible errors. Monitor operations may fail if, for example, the underlying thread implementation cannot allocate the resources necessary to perform the monitor operation.

5512/26/2012

MonitorEnter and MonitorExit work on jclass, jstring, and jarray types, which are special kinds of jobject references.

Remember to match a MonitorEnter call with the appropriate number of MonitorExit calls, especially in code that handles errors and exceptions:if ((*env)->MonitorEnter(env, obj) != JNI_OK) ...;...if ((*env)->ExceptionOccurred(env)) {... /* exception handling *//* remember to call MonitorExit here */if ((*env)->MonitorExit(env, obj) != JNI_OK) ...;}... /* Normal execution path.if ((*env)->MonitorExit(env, obj) != JNI_OK) ...;

5612/26/2012

Failure to call MonitorExit will most likely lead to deadlocks. By comparing the above C code segment with the code segment at the beginning of

this section, user can appreciate how much easier it is to program with the Java programming language than with the JNI.

Thus, it is preferable to express synchronization constructs in the Java programming language.

If, for example, a static native method needs to enter the monitor associated with its defining class, we should define a static synchronized native method as opposed to performing JNI-level monitor synchronization in native code.

5712/26/2012

Monitor Wait and NotifyThe Java API contains several other methods that are

useful for thread synchronization. They are Object.wait, Object.notify, and

Object.notifyAll. No JNI functions are supplied that correspond directly

to these methods because monitor wait and notify operations are not as performance critical as monitor enter and exit operations.

Native code may instead use the JNI method call mechanism to invoke the corresponding methods in the Java API:

5812/26/2012

/* precomputed method IDs */static jmethodID MID_Object_wait;static jmethodID MID_Object_notify;static jmethodID MID_Object_notifyAll;void JNU_MonitorWait(JNIEnv *env, jobject object, jlong timeout){(*env)->CallVoidMethod(env, object, MID_Object_wait, timeout); }

Void JNU_MonitorNotify(JNIEnv *env, jobject object){ (*env)->CallVoidMethod(env, object, MID_Object_notify); }

Void JNU_MonitorNotifyAll(JNIEnv *env, jobject object){(*env)->CallVoidMethod(env, object, MID_Object_notifyAll); }

5912/26/2012

User assume that the method IDs for Object.wait, Object.notify, and Object.notifyAll have beencalculated elsewhere and are cached in the global variables.

Like in the Java programming language, user can call the above monitor-related functions only when holding the monitor associated with the jobject argument.

6012/26/2012

Obtaining a JNIEnv Pointer in Arbitrary Contextsexplained earlier that a JNIEnv pointer is only valid in its associated thread. This is generally not a problem for native methods because they receive the JNIEnv

pointer from the virtual machine as thefirst argument.

Occasionally, however, it may be necessary for a piece of native code not called directly from the virtual machine to obtain the JNIEnv interface pointer that belongs to the current thread.

For example, the piece of native code may belong to a "callback" function called by the operating system, in which case the JNIEnv pointer will probably not be available as an argument.

6112/26/2012

User can obtain the JNIEnv pointer for the current thread by calling the AttachCurrentThread function of the invocation interface:JavaVM *jvm; /* already set */f(){JNIEnv *env;(*jvm)->AttachCurrentThread(jvm, (void **)&env, NULL);... /* use env */}

When the current thread is already attached to the virtual machine, Attach-Current-Thread returns the JNIEnv interface pointer that belongs to the current thread.

6212/26/2012

There are many ways to obtain the JavaVM pointer: by recording it when the virtual machine is created, by querying for the created virtual machines using JNI_GetCreatedJavaVMs, by calling the JNI function GetJavaVMinside a regular native method, or by defining a JNI_OnLoad handler.

Unlike the JNIEnv pointer, the JavaVM pointer remains valid across multiple threads so it can be cached in a global variable.

Java 2 SDK release 1.2 provides a new invocation interface function GetEnv so that you can check whether the current thread is attached to the virtual machine, and, if so, to return the JNIEnv pointer that belongs to the current thread.

GetEnv and AttachCurrentThread are functionally equivalent if the current thread is already attached to the virtual machine.