More Specifically JNI Justin Catterson. ADA C++ Java Ruby Python Haskell Perl etc. What is a...

Post on 17-Dec-2015

228 views 0 download

Transcript of More Specifically JNI Justin Catterson. ADA C++ Java Ruby Python Haskell Perl etc. What is a...

FOREIGN FUNCTION INTERFACEMore 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 1997Used 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

1. Add to the system variable path the location of your JDK bin (ie. C:\Program Files (x86)\Java\jdk1.6.0_20\bin)

2. Write java class with at least one method declared native (ie. Public native void hello() )

3. Add call to System.loadLibrary (ie. Static { System.loadLibrary(“hello”);}

4. Compile java code using javac

BASIC STEPS JAVA TO CTHROUGH COMMAND PROMPT

5. Create header file for the c using javah6. Write native method for hello7. with microsoft visual studio, execute the

vcvarsall.bat in the vc directory of visual studio

8. 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

9. Run the java program

RUN EXAMPLE

jni

Extra Parameters?

1. JNIEnv pointer contains the location of the function table

2. 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 int atol(String str);

}

JNIExport jint JNICALLJava_C_atol(JNIEnv *env, jclass cls, jstring str){

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++)

1. Write the Java code2. Compile java3. Write C++4. Compile C++5. run the exe (Ensure you have the JVM dll

directory in the system variable path)

RUN EXAMPLE

cToJava

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++

1. HeapSort ( Memory )2. 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/Li

nearSystems/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

Results

Why the performance hit at size 10,000 for JNI?

Not expensive enough to not useStill has cost associated pending the JIT800-1350 ns per call + 25 to 30ns for each argument (Dawid Kurzyniec and Vaidy Sunderam)

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

Types1. Primitive

2. Reference

Primitive Types

Java Language Type Native Type Description

boolean jboolean Unsigned 8 bits

byte jbyte Signed 8 bits

Char jchar Unsigned 16 bits

short jshort Signed 16bits

int jint Signed 32 bits

long jlong Signed 64 bits

float jfloat 32 bits

double jdouble 64 bits

Reference Types (opaque refrences)

All JNI objects inherit from jObject

Treated as pointers

Opaque References

1. Local 2. Global3. Weak

Local References

Content that is created from a native method will only exist during the execution of the native method.

Memory corruptionsOr system crashesAttempted to use invalidLocal address

jstring MyNewString(JNIEnv *env, jchar *chars, jint len) { static jclass stringClass = NULL; jmethodID cid; jcharArray elemArr; 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

jstringMyNewString(JNIEnv *env, jchar *chars, jint len){static jclass stringClass = NULL;...if (stringClass == NULL) {jclass localRefCls =(*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 Similar to Global references

Valid across native methods and threads

Don’t care if object gets GC

JNIEXPORT void JNICALLJava_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 */}

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; Srimat Chakradhar; Anand Raghunathan; 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] Dawid Kurzyniec; Vaidy Sunderam. 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] Preetham Chandrian (August 2011). Efficient Java Native Interface for Android based

Mobile Devices. Retrieved from http://repository.asu.edu/items/9315