JNI is a native programming interface. It allows Java code running in a Java Virtual Machine (VM) to interoperate with applications and libraries written in other programming languages, such as C, C++, and assembly.

The most important advantage of JNI is that it does not limit the implementation of the underlying JVM. As a result, JVM vendors can add support for JNI without affecting other parts of the JVM. A programmer can write a version of a native application or library and expect it to work with all JNI-enabled JVMS.

A review of JNI

While it is possible to write applications entirely in Java, in some cases Java alone does not meet the requirements of the application. When applications cannot be written entirely in Java, programmers use JNI to write Java native methods to handle these situations.

The following example illustrates when Java native methods are needed:

  • Standard Java class libraries do not support platform-dependent features required by applications.
  • We already have a library written in another language that we want Java code to access through JNI.
  • You want to implement a small amount of time-sensitive code in a lower-level language such as assembly language.
  • Native methods that can be used with JNI programming:
  1. Create, examine, and update Java objects, including arrays and strings.
  2. Call the Java method.
  3. Catch and throw exceptions.
  4. Load the class and get the class information.
  5. Perform runtime type checking.

We can also use JNI and call apis to support arbitrary native application embedding into the JVM. This allows programmers to easily enable Java in their existing applications without having to link to VM source code.

Ii. Historical background

VMS from different vendors provide different native method interfaces. These different interfaces force programmers to generate, maintain, and distribute multiple versions of local method libraries on a given platform.

Some local method interfaces are briefly introduced, such as:

  • JDK 1.0 native method interface
  • Netscape’s Java runtime interface
  • Microsoft’s native and Java/COM interfaces

Three, goals,

A unified, well-thought-out standard interface provides the following benefits for everyone:

  • Each VM vendor can support more native code.
  • The tool builder does not have to maintain different kinds of native method interfaces.
  • Application programmers will be able to write a version of native code that will run on different VMS.

A standard native method interface must meet the following requirements:

1. Binary compatibility — The main goal is to span all Java on a given platform

2. Binary compatibility of native method libraries implemented by the VM. For a given platform, programmers should maintain only one version of the local method library.

3. Efficiency — To support time-sensitive code, the native method interface must impose minimal overhead. All the known techniques for ensuring VM independence (and binary compatibility) come with some overhead. A compromise must be reached between efficiency and virtual machine independence.

4. Functionality — The interface must expose enough of the JVM’s interior to allow native methods to accomplish useful tasks.

4. JNI programming

Native method programmers should program for JNI. Programming for JNI shields the programmer from unknowns, such as the vendor’s VM that the end user might be running. By following the JNI standard, you give native libraries the best chance of running in a given JVM.

If you are implementing the JVM, you should implement JNI. JNI has been tested over time to ensure that it does not impose any overhead or restrictions on the VM implementation, including object representation, garbage collection schemes, and so on.

Five, side effects

Once JNI is used, JAVA programs lose two advantages of the JAVA platform:

  • Applications are no longer cross-platform. To be cross-platform, you must recompile the native language parts in a different system environment.
  • Programs are no longer perfectly safe, and improper use of native code can cause the entire program to crash. As a general rule, you should have local methods concentrated in a few classes. This reduces the coupling between JAVA and native code.

Six, change

As of Java SE 6.0, the deprecated structures JDK1_1InitArgs and JDK1_1AttachArgs have been removed in favor of JavaVMInitArgs and JavaVMAttachArgs.