This chapter introduces the Java Native Interface (JNI). The JNI is a native programming interface. It allows Java code that runs inside a Java Virtual Machine (VM) to interoperate with applications and libraries written in other programming languages, such as C, C++, and assembly.
Java Native Interface Overview
While you can write applications entirely in Java, there are situations where Java alone does not meet the needs of your application. Programmers use the JNI to write Java native methods to handle those situations when an application cannot be written entirely in Java.
The following examples illustrate when you need to use Java native methods:
- The standard Java class library does not support the platform-dependent features needed by the application.
- You already have a library written in another language, and wish to make it accessible to Java code through the JNI.
- You want to implement a small portion of time-critical code in a lower-level language such as assembly.
By programming through the JNI, you can use native methods to:
- Create, inspect, and update Java objects (including arrays and strings).
- Call Java methods.
- Catch and throw exceptions.
- Load classes and obtain class information.
- Perform runtime type checking.
You can also use the JNI with the Invocation API to enable an arbitrary native application to embed the Java VM. This allows programmers to easily make their existing applications Java-enabled without having to link with the VM source code.
Integrity Concerns
The use of native code in general and of JNI in particular imposes risks to the integrity of Java applications.
Native code may exhibit undefined behavior which may lead to process crashes or other undesirable unspecified behavior.
Native JNI methods may create a direct byte buffer addressing illegal memory and pass it to Java code. This may lead to undefined behavior triggered by the Java code interacting with the direct byte buffer.
Native JNI methods may call private methods, read or write private fields, and generally access and manipulate Java objects without regard to access control.
Consequently, the use of JNI is restricted. For a Java module to make use of JNI it must enable native access (see Chapter 2: Design Overview).
Loading native libraries or declaring native methods in
modules without native access will result in exceptions and/or
warnings.
Many of the uses of JNI can be achieved with the newer Foreign Function & Memory API (FFM), which should be preferred over JNI.