420 likes | 555 Views
Foreign Function Interface. More Specifically JNI Justin Catterson. Most languages have a foreign function interface. ADA C++ Java Ruby Python Haskell Perl etc. What is a Foreign Function Interface?. Simply an interface which allows languages to interact with one another.
E N D
Foreign Function Interface More Specifically JNI Justin Catterson
Most languages have a foreign function interface • ADA • C++ • Java • Ruby • Python • Haskell • Perl • etc. What is a Foreign Function Interface? Simply an interface which allows languages to interact with one another
Reasons for needing Foreign Function Interfaces • Reuse of Legacy Code • Add libraries to language (Object Oriented) • Performance
JNI (Java Native Interface) Released in 1997 Used to call native methods Used to embed a Java Virtual Machine into native applications Suns JDK 1.4.2 contains over 600,00 lines of native C code
Issues with JNI • Software Security • Loss of Portability • Mapping is not easy • Only supports C/C++ can do Ada, Fortran, COBOL but it is more difficult • Strong knowledge in both Java and C • Overhead?
When should I use JNI? When to use • Java API doesn’t support certain features required by application • Want to access an existing library • Implement time-critical sections in a low level language • Multiple processes are taking up too much memory When NOT to use • When you could communicate with native language through TCP/IP connection • Could connect to database using JDBC • Distributed object technology such as Java IDL API
Goals of JNI • Binary Compatibility • Little overhead • Native methods full use of JVM • Not the only FFI available for Java
Design Principles • Make control flow as simplistic as possible • Keep native code minimal (Error checking) • Isolate native code (“Porting layer”)
Basic steps Java to Cthrough command prompt • Add to the system variable path the location of your JDK bin (ie. C:\Program Files (x86)\Java\jdk1.6.0_20\bin) • Write java class with at least one method declared native (ie. Public native void hello() ) • Add call to System.loadLibrary (ie. Static { System.loadLibrary(“hello”);} • Compile java code using javac
Basic steps Java to Cthrough command prompt Create header file for the c using javah Write native method for hello with microsoft visual studio, execute the vcvarsall.bat in the vc directory of visual studio Compile native file into a dll (using cl -Iinclude -Iinclude\win32 -MD -LD hello.cpp -Fejnihello.dll) –l is where the include and include\win32 directories are from the jdk Run the java program
Run example jni
Extra Parameters? • JNIEnv pointer contains the location of the function table • If method is (java static), the method belongs to the java class that contains the native function
How do we use an existing native library? One-to-one mapping public class C { public static native intatol(String str); } JNIExportjint JNICALL Java_C_atol(JNIEnv *env, jclasscls, jstringstr) { const char *cstr = env->GetStringUTFChars(str, 0); if (cstr == NULL) { return 0; // out of memory } int result = atol(cstr); env->ReleaseStringUTFChars(str, cstr); return result; }
C++ to Java (Embed JVM into C++) • Write the Java code • Compile java • Write C++ • Compile C++ • run the exe (Ensure you have the JVM dll directory in the system variable path)
Run example cToJava
JNI functions • http://download.oracle.com/javase/1.5.0/docs/guide/jni/spec/functions.html
JNI and Performance • Typically accepted C and C++ is faster than Java • Is it expensive to make the call through JNI?
Experiment Run benchmark tests to measure execution time between two algorithms in Java and C++ • HeapSort ( Memory ) • Discrete Fast Fourier Transform ( Heavy Math)
Discrete Fast Fourier Transform • Check java’s performance for mathematical computations • If you are interested in learning more • http://home.comcast.net/~szemengtan/LinearSystems/fft.pdf
HeapSort • Array sizes of 250, 1000, and 10000. To check the impact of array sizes on Java and JNI • Vary number of iterations to check start-up cost
Not expensive enough to not use Still has cost associated pending the JIT 800-1350 ns per call + 25 to 30ns for each argument (DawidKurzyniec and VaidySunderam)
How to handle overhead cost? • JVM memory and native memory space transfer (hash map store recently accessed fieldids and methods) • Arrays primary concern ( Try to avoid passing them) • Pending VM may make copy
Types • Primitive • Reference
Reference Types (opaque refrences) All JNI objects inherit from jObject Treated as pointers
Opaque References • Local • Global • Weak
Local References • Content that is created from a native method will only exist during the execution of the native method. Memory corruptions Or system crashes Attempted to use invalid Local address jstring MyNewString(JNIEnv *env, jchar *chars, jintlen) { static jclassstringClass = NULL; jmethodID cid; jcharArrayelemArr; jstring result; if (stringClass == NULL) { stringClass = (*env)->FindClass(env, "java/lang/String"); if (stringClass == NULL) { return NULL; /* exception thrown */ }} /* It is wrong to use the cached stringClass here, because it may be invalid. */ cid = (*env)->GetMethodID(env, stringClass, "<init>", "([C)V"); ... elemArr = (*env)->NewCharArray(env, len); ... result = (*env)->NewObject(env, stringClass, cid, elemArr); (*env)->DeleteLocalRef(env, elemArr); return result; }
Global References • Exists until the programmer deletes the object • No GC jstring MyNewString(JNIEnv *env, jchar *chars, jintlen) { static jclassstringClass = NULL; ... if (stringClass == NULL) { jclasslocalRefCls = (*env)->FindClass(env, "java/lang/String"); if (localRefCls == NULL) { return NULL; /* exception thrown */ } /* Create a global reference */ stringClass = (*env)->NewGlobalRef(env, localRefCls); /* The local reference is no longer useful */ (*env)->DeleteLocalRef(env, localRefCls); /* Is the global reference created successfully? */ if (stringClass == NULL) { return NULL; /* out of memory exception thrown */ } } ... } NewGlobalRef
Weak References JNIEXPORT void JNICALL Java_mypkg_MyCls_f(JNIEnv *env, jobject self) { static jclass myCls2 = NULL; if (myCls2 == NULL) { jclass myCls2Local = (*env)->FindClass(env, "mypkg/MyCls2"); if (myCls2Local == NULL) { return; /* can’t find class */ } myCls2 = NewWeakGlobalRef(env, myCls2Local); if (myCls2 == NULL) { return; /* out of memory */ } } ... /* use myCls2 */ } • Similar to Global references • Valid across native methods and threads • Don’t care if object gets GC
Threading and JNI • JNIenv pointer cannot cache must pass pointer associated with the specific thread • Local references valid only for thread that created it, pass global references • Synchronization use MoniterEnter/MoniterExit
Problems • Safety Guarantees • Safe Language + Unsafe Language = unsafe • C code is unsafe, you may read/write to any memory address • C code can pass objects of wrong type back to Java and therefore violate Java's type checks • Memory Mangement ( calls to release)
How Read/Write problems occur • Private? Constants? • From references, C can see private data and change the values of constants • Interface pointers, this is how C can use Java’s functions. C can overwrite the entries in the function table. • Array Index out of bounds, accidently read/write directly to Java’s heap
Solution? • Safe interoperation (Remote Prodecure Calls) • Ccured (pointer arithmetic solutions) • SafeJNI (wrap JNI api calls) • Jeannie
Remote Procedure Calls • Place components in different address space • Significant overhead
Ccured • Internal safety for C code • Separates pointers by usage • Helps remove array index out of bounds errors
Applications • Real-Time Embedded • Use Java for upper levels (UI, threading, networking) • Have C++/C interface with hardware and signaling, support already exists
Android NDK C • Hardware sensors • Platform operations • 3D libraries Android (JavaME) -- Linux
Conclusions • Use JNI to expand language libraries/ use legacy programs • JNI useful for embedded systems • Java can be easily abused using JNI • Keep native methods in the same “package”
References • 1] Sheng Liang (June 1999). The Java Native Interface Programmer’s Guide and Specification. Retrieved from http://java.sun.com/docs/books/jni/download/jni.pdf • [2] Gang Tan; Andrew W. Appel; SrimatChakradhar; AnandRaghunathan; Srivaths Ravi; Daniel Wang (2006). Safe Java Native Interface.Retrieved from http://www.cs.princeton.edu/~appel/papers/safejni.pdf • [3] Scott Stricker(March 2002). Java Programming with JNI. • Retrieved from http://www.ibm.com/developerworks/java/tutorials/j-jni/ • [4] DawidKurzyniec; VaidySunderam. Efficient Cooperation between Java and Native • Codes - JNI Performance Benchmark. • Retrieved from http://janet-project.sourceforge.net/papers/jnibench.pdf • [5] Demetrius L. Davis. To JNI or not to JNI? • Retrieved from http://www.ewp.rpi.edu/hartford/~rhb/cs_seminar_2004/SessionC3/davis.pdf • [6] PreethamChandrian (August 2011). Efficient Java Native Interface for Android based Mobile Devices. • Retrieved from http://repository.asu.edu/items/9315