This article has multiple issues.Please helpimprove itor discuss these issues on thetalk page.(Learn how and when to remove these messages)
|
Insoftware design,theJava Native Interface(JNI) is aforeign function interfaceprogrammingframeworkthat enablesJavacode running in aJava virtual machine(JVM) to call and be called by[1]native applications (programs specific to a hardware andoperating systemplatform) andlibrarieswritten in other languages such asC,C++andassembly.
Objectives
editJNI enables programmers to write native methods to handle situations when an application cannot be written entirely in the Java programming language, e.g. when the standard Javaclasslibrarydoes not support the platform-specific features or program library. It is also used to modify an existing application (written in another programming language) to be accessible to Java applications. Many of the standard library classes depend on JNI to provide functionality to the developer and the user, e.g. file I/O and sound capabilities. Including performance- and platform-sensitive API implementations in the standard library allows all Java applications to access this functionality in a safe and platform-independent manner.
The JNI framework lets a native method use Javaobjectsin the same way that Java code uses these objects. A native method can create Java objects and then inspect and use these objects to perform its tasks. A native method can also inspect and use objects created by Java application code.
Only applications and signed applets can invoke JNI.
An application that relies on JNI loses the platform portability Java offers (a partial workaround is to write a separate implementation of JNI code for each platform and have Java detect the operating system and load the correct one at runtime).
Not only can native code interface with Java, it can also draw on a JavaCanvas
,which is possible with theJava AWT Native Interface.The process is almost the same, with just a few changes. The Java AWT Native Interface is only available sinceJ2SE1.3.
JNI also allows direct access toassembly code,without even going through aCbridge.[2]Accessing Java applications from assembly is possible in the same way.[3]
Design
editIn the JNI framework, native functions are implemented in separate.c or.cpp files. (C++ provides a slightly simpler interface with JNI.) When the JVM invokes the function, it passes aJNIEnv
pointer, ajobject
pointer, and any Java arguments declared by the Java method. For example, the following converts a Java string to a native string:
extern"C"
JNIEXPORTvoidJNICALLJava_ClassName_MethodName
(JNIEnv*env,jobjectobj,jstringjavaString)
{
constchar*nativeString=env->GetStringUTFChars(javaString,0);
//Do something with the nativeString
env->ReleaseStringUTFChars(javaString,nativeString);
}
Theenv
pointer is a structure that contains the interface to the JVM. It includes all of the functions necessary to interact with the JVM and to work with Java objects. Example JNI functions are converting native arrays to/from Java arrays, converting native strings to/from Java strings, instantiating objects, throwing exceptions, etc. Basically, anything that Java code can do can be done usingJNIEnv
,albeit with considerably less ease.
The argumentobj
is a reference to the Java object inside which this native method has been declared.
Nativedata typescan be mapped to/from Java data types. For compound types such as objects,arraysandstringsthe native code must explicitly convert the data by calling methods in theJNIEnv
.
A JNI environment pointer (JNIEnv*) is passed as an argument for each native function mapped to a Java method, allowing for interaction with the JNI environment within the native method. This JNI interface pointer can be stored, but remains valid only in the current thread. Other threads must first callAttachCurrentThread()to attach themselves to the VM and obtain a JNI interface pointer. Once attached, a native thread works like a regular Java thread running within a native method. The native thread remains attached to the VM until it callsDetachCurrentThread()to detach itself.[4]
The JNI framework does not provide any automatic garbage collection for non-JVM memory resources allocated by code executing on the native side. Consequently, native side code (such as assembly language) assumes the responsibility for explicitly releasing any such memory resources that the native code acquires.
On Linux and Solaris platforms, if the native code registers itself as a signal handler, it could intercept signals intended for the JVM. Achain of responsibilitycan be used to allow native code to better inter-operate with the JVM. On Windows platforms,Structured Exception Handling (SEH)may be employed to wrap native code in SEH try/catch blocks so as to capture machine (CPU/FPU) generated software interrupts (such as NULL pointer access violations and divide-by-zero operations), and to handle these situations before the interrupt is propagated back up into the JVM (i.e. Java side code), in all likelihood resulting in an unhandled exception.[original research?]
The encoding used for the NewStringUTF, GetStringUTFLength, GetStringUTFChars, ReleaseStringUTFChars and GetStringUTFRegion functions is "modified UTF-8",[5]which is not valid UTF-8 for all inputs, but a different encoding really. The null character (U+0000) and codepoints not on theBasic Multilingual Plane(greater than or equal to U+10000, i.e. those represented assurrogate pairsin UTF-16) are encoded differently in modified UTF-8. Many programs actually use these functions incorrectly and treat the UTF-8 strings returned or passed into the functions as standard UTF-8 strings instead of modified UTF-8 strings. Programs should use the NewString, GetStringLength, GetStringChars, ReleaseStringChars, GetStringRegion, GetStringCritical and ReleaseStringCritical functions, which use UTF-16LE encoding on little-endian architectures and UTF-16BE on big-endian architectures, and then use a UTF-16 to UTF-8 conversion routine.[original research?]
Mapping types
editThe following table shows the mapping of types between Java (JNI) and native code.
C Type | Java Language Type | Description | Type signature |
---|---|---|---|
unsigned char uint8_t |
jboolean | unsigned 8 bits | Z |
signed char int8_t |
jbyte | signed 8 bits | B |
unsigned short uint16_t |
jchar | unsigned 16 bits | C |
short int16_t |
jshort | signed 16 bits | S |
int int32_t |
jint | signed 32 bits | I |
long long int64_t |
jlong | signed 64 bits | J |
float | jfloat | 32 bits | F |
double | jdouble | 64 bits | D |
void | V |
In addition, the signature"L fully-qualified-class;"
would mean the class uniquely specified by that name; e.g., the signature"Ljava/lang/String;"
refers to the classjava.lang.String
.Also, prefi xing[
to the signature makes the array of that type; for example,[I
means the int array type. Finally, avoid
signature uses theV
code.
These types are interchangeable. One can usejint
where you normally use anint
,and vice versa, without anytypecastingrequired. However, mapping between Java Strings and arrays to native strings and arrays is different. If ajstring
is used where achar *
would be, the code could crash the JVM.[original research?]
Performance
editJNI incurs considerable overhead and performance loss under certain circumstances:[6]
- Function calls to JNI methods are expensive, especially when calling a method repeatedly.
- Native methods are not inlined by the JVM, nor can the method beJIT compiled,as the method is already compiled.
- A Java array may be copied for access in native code, and later copied back. The cost can be linear in the size of the array.
- If the method is passed an object, or needs to make a callback, then the native method will likely be making its own calls to the JVM. Accessing Java fields, methods and types from the native code requires something similar toreflection.Signatures are specified in strings and queried from the JVM. This is both slow and error-prone.
- Java Strings are objects, have length and are encoded. Accessing or creating a string may require an O(n) copy.
Alternatives
editMicrosoft's proprietary implementation of a Java Virtual Machine (Visual J++) had a similar mechanism for calling native code from Java, called theRaw Native Interface(RNI). In addition, it had an easy way to call existing native code that was not itself aware of Java, such as (but not limited to) the Windows API, calledJ/Direct.However, following theSun–Microsoft litigationabout this implementation,Visual J++is no longer maintained.
RNI was less clumsy to use than JNI, because no bookkeeping with a Java environment pointer was needed. Instead, all Java objects could be accessed directly. To facilitate this, a tool was used that generated header files from Java classes. Similarly, J/Direct was easier to use than using the necessary intermediate native library and JNI.
Java Native Access (JNA)is a community-developed library that provides Java programers easy access to native shared libraries without using JNI. However, this requires the redistribution of the dependent jar library. The tradeoff is between JNI being harder to code and JNA being slower.[7]JNI is built in to core Java.
See also
editReferences
edit- ^"Java Native Interface Overview".The Java Native Interface Programmer's Guide and Specification.Retrieved2018-12-27.
- ^"Invoking Assembly Language Programs from Java".Java.net. 2006-10-19. Archived fromthe originalon 2008-03-30.Retrieved2007-10-06.
- ^"Launch Java Applications from Assembly Language Programs".Java.net. 2006-10-19. Archived fromthe originalon 2007-10-11.Retrieved2007-10-04.
- ^The Invocation API. Sun Microsystems.https://docs.oracle /en/java/javase/11/docs/specs/jni/invocation.html
- ^"JNI Types and Data Structures".
- ^"java — What makes JNI calls slow? - Stack Overflow".
- ^Zakusylo, Alexander."Github is also the original JNA source. JNA vs JNI benchmark speed tests".Github.Github.Retrieved30 March2023.
Bibliography
edit- Gordon, Rob (March 1998).Essential Jni: Java Native Interface(1st ed.).Prentice Hall.p. 498.ISBN0-13-679895-0.
- Liang, Sheng (June 20, 1999).Java(TM) Native Interface: Programmer's Guide and Specification(1st ed.).Prentice Hall.p. 320.ISBN0-201-32577-2.