1 / 36

Native Methods

Native Methods. W.H.Carlisle CSE525. Native Methods: procedures implemented in a language other than Java. Reasons To use To interface with special capabilities of a computer not supported by a Java class interface to a new device utilize a library routine of some native os

metea
Download Presentation

Native Methods

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Native Methods W.H.Carlisle CSE525

  2. Native Methods: procedures implemented in a language other than Java • Reasons To use • To interface with special capabilities of a computer not supported by a Java class • interface to a new device • utilize a library routine of some native os • Speed (be careful here) • better is JIT Compiler or java2c translator

  3. Native Methods: procedures implemented in a language other than Java • Reasons not to use • Lose portabality • class can never be used in applet code. • no applet allowed to load a class that has a native method.

  4. BUT - in order to have a lecture we assume some method HAS to be native

  5. Different Virtual Machines • Java VMs may differ. • The 1.0 native method framework was specific to Sun’s VM • Java 1.1 introduced JNI (Java Native Interface) that is an API for a “VM Neutral” native method interface.

  6. Step 1: the Java side • Write the Java code • the native methods in the class is declared “native” • the native methods in the class have no body, just an ending semicolon • a static class initializer is added to the class to load the native code library we will build next.

  7. public class HelloWorld { public native void displayHelloWorld(); static { System.loadLibrary(“hello”); } }

  8. public class Cls { private int a; native double f(int i, String s ); public native void close(); static { try {System.loadLibrary(“Cls”);} catch(Throable t) {System.err.println(“Error Loading Library”);} } // calling the native method public static void main(String[] args) { double d = (new Cls()).f(3,”hello”);} }

  9. Programmer … 1. Declares the method as native 2. Insure that the native library is loaded by the JVM System.load System.loadLibrary 3. Then the call to the native method dispatches to the dynamic link library.

  10. Type encoding To invoke native code or for native methods to make JNI API calls, Java types are sometimes encoded Java primitive types are encoded with a single character: Z boolean F float B byte D double C character V void S short I int J long [x array-of-x Lname; object

  11. VM encoding • If the name of the java method is testjni.Cls.f() • the VM uses Java_testjni_Cls_f as the name of the function. • If the java method is overloaded the name is appended with two underscores and the argument types.

  12. VM encoding • If the java method is overloaded the name is appended with two underscores and the argument types. • Suppose the java overloaded method is testjni.Cls.f(int,String) • The name of the function will be Java_testjni_Cls_f__ILjava_lang_String_2

  13. Name Munging • Name Munging is required to generate a unique legal identifier in the native language. • ‘.’ or ‘/’ in names become _ • unicode becomes ‘_0xxxx’ • a ‘_’ becomes ‘_1’ • ‘;’ becomes ‘_2’ • ‘[‘becomes ‘_3’

  14. Arguments • Native method arguments have • A JNI environment pointer • a jobject or jclass • Other arguments correspond to the real arguments boolean jboolean byte jbyte char jchar void void etc…. • and we begin to suspect that “native” means C

  15. Arguments • if java prototype in class Cls is native double f(int, String); • the native prototype is idouble Java_testjni_Cls_f__ILjava_lang_String_2(JNIEnv*, jboject, jint, jstring); One does not have to learn how to mungle!

  16. Step 2: compile the Java code • this produces the file HelloWorld.class which will be fed to step 3

  17. Now we confirm that for all practical purposes native method means C code • (to be fair, I have seen discussion of native methods in Ada but have not followed up on this)

  18. Step 3 : use javah to create a header file javah -jni HelloWorld • run on the HelloWorld.class this places a HelloWorld.h file in the directory…but a -d option can place it elsewhere. • natïve methods are mungled and incorporated into the header file.

  19. Look at, but do not edit the .h file /* DO NOT EDIT THIS FILE - it is machine generated */ #include <jni.h> /* Header for class HelloWorld */ #ifndef _Included_HelloWorld #define _Included_HelloWorld #ifdef __cplusplus extern "C" { #endif /* * Class: HelloWorld * Method: displayHelloWorld * Signature: ()V */ JNIEXPORT void JNICALL Java_HelloWorld_displayHelloWorld (JNIEnv *, jobject); #ifdef __cplusplus } #endif #endif

  20. /* DO NOT EDIT THIS FILE - it is machine generated */ #include <jni.h> /* Header for class Cls */ #ifndef _Included_Cls #define _Included_Cls #ifdef __cplusplus extern "C" { #endif /* * Class: Cls * Method: f * Signature: (ILjava/lang/String;)D */ JNIEXPORT jdouble JNICALL Java_Cls_f (JNIEnv *, jobject, jint, jstring); #ifdef __cplusplus } #endif #endif

  21. The C function(s) are what you look at since this is the prototype for the function you will write JNIEXPORT void JNICALL Java_HelloWorld_displayHelloWorld (JNIEnv *, jobject); JNIEXPORT jdouble JNICALL Java_Cls_f(JNIEnv *, jobject, jint, jstring);

  22. The interface pointer • This is a pointer to all the library methods available to the native method. • The table of functions is loaded by the VM for a thread • Thus between disjoint threads the pointer may not be valid.M

  23. Using the pointer • To access a java field from within a native method use: env-> GetXXXField(obj,fld) • or env -> SetXXXField(obj,fld,value) e.g. env-> SetIntField(obj,fld,3) • fld is a jfieldID and is a handle to the field used by C functions

  24. getting the jfieldID • To get this ID (an offset of a field in a class) use jfieldID GetFieldID(jclass c, //Class const char* name, //name const char* type); // typecode jfieldID fld = env->GetFieldID( Cls, “a”, “I”) ; for an int a; field in a java class named Cls

  25. Javap • The command javap -s -p MyClass gives the field and method signatures.

  26. Step 5: Write the C function(s) • include the correct header file #include “Cls.h” • include any other C stuff (e.g. <stdio.h> • Implement the functions using the signatures defined in the .h file

  27. #include “Cls.h” JNIEXPORT jdouble JNICALL Java_Cls_f (JNIEnv *env, jobject obj, jint i, jstring str);{ //read a field out of the calling object jclass cls = env-> GetObjectClass(obj); jfieldID a = env->GetFieldID(cls,”a”,I); jint i = evn->GetIntField(obj,a); //change its value env->SetIntField(obj,a,++i); //convert paramater from javastring char* cStr = env-> GetStringUTFChars(str,NULL); //with a java string to C string function return 2.2; }

  28. Method Invocation • Access to methods of an object calling a native method are similar to field access. • Invoke non-static methods with CallXXXMethod() • Invoke static methods with CallStaticXXXMethod() where XXX is the returnType. • A GetMethodID() or GetStaticMethodID give the required jmethodID used as parameters in the Call.

  29. Example public class Cls { public native void f2( Cback cb); } public class Cback { public static void s1(String s) {…} public Date m1( int m, int d, int y) {…} }

  30. Method call #include “Cls.h” JNIEXPORT void JNICALL Java_CLs_f2 (JNIEnv* env, jobject obj, jobjet cback) { jclass cls = env-> GetObjectClass(cback); jmethodID m = env-> GetMethodID( cls,”m1”,”(III)Ljava/util/Date;”); //now java’s cback.m1(2,1,61) jobject date = env->CallObjetMethod (cback, m, 2, 1, 61); jmethodID s = env->GetStaticMethodID (cls,”s1”,”(Ljava/lang/String;)V”); jstring str = env-> NetStringUTF(“Boo”); nv->CallStaticVoidMethod(cls,s,str); }

  31. Exceptions • Exceptions can occur from a native method call to a java method. • Native methods can • throw an exception: ThrowNew • check a pending exception:ExceptionOccurred • handle and clear exceptions:ExceptionClear • Query the stack trace: ExceptionDescribe • throw example jclass exceptionClass = env->FindClass(“java/lang/Exception); env->ThrowNew(exceptionClass, “genException()”);

  32. Step6: Create the dynamically loadable library • These are C compiler/OS issues. • I believe the gcc/unix compiler command to be gcc -G X.c -o libhello.so • An IBM C++ compiler for Win95 uses icc /Ge- /Gm+ /Mt /B”/Def:javai.lib” xyz.cpp • Key words to look for are • relocatable • dynamically linkable (DLL) library

  33. Step 7: Run the program • In UNIX, if you get java.lang.NullPointerException at java.lang.Runtime.loadLibrary... then the os loader needs to have a library path set in your shell environment to the directory in which the library lives.

  34. If you get java.lang.UnsatisfiedLinkError no hello in LD_LIBRARY_PATH at java.lang.Throwable…. then the loader has a library path set in your environment, but it does not include the directory in which the file lives.

  35. Other interface issues • Threads and native methods • native methods must be thread safe • C programs that want a Java virtual machine.

  36. Starting a Java VM • The JDK1.1 Invocation API permits startup of a JVM from C code. JavaVM = *jvm; JNIEnv *env; JavaVMInitArgs args; JNI_GetDefaultJavaVMInitArgs(&args); JNI_CreatJavaVM( &jvm, &env, &args); // now call a static method of MyClass jclass cls = env->FindClss(“MyClass”); jmethodID m = env->getStaticMethodID( cls,”s2”,”(I)V”); env->CallStaticVoidMethod(cls,m,15); jvm->DestroyJavaVM();

More Related