Java Native Interface Notes
Java Native Interface Notes
The Java Native Interface (JNI) is a framework that allows your Java
code to call native applications and libraries written in languages such
as C, C++ and Objective-C. To be honest, if you have any other choice besides using JNI,
do that other thing.
To achieve this, the JDK introduces a bridge between the bytecode running in our
JVM and the native code (usually written in C or C++).
The tool is called Java Native Interface.
Static libs – all library binaries will be included as part of our executable during the
linking process. Thus, we won't need the libs anymore, but it'll increase the size of our
executable file.
Shared libs – the final executable only has references to the libs, not the code itself. It
requires that the environment in which we run our executable has access to all the
files of the libs used by our program.
The latter is what makes sense for JNI as we can't mix bytecode and natively compiled code
into the same binary file.
Therefore, our shared lib will keep the native code separately within its .so/.dll/.dylib file
(depending on which Operating System we're using) instead of being part of our classes.
The native keyword transforms our method into a sort of abstract method:
1 private native void aNativeMethod();
With the main difference that instead of being implemented by another Java class, it will
be implemented in a separated native shared library.
Components Needed
Key components that we need to take into account.
Java Code – our classes. They will include at least one native method.
Native Code – the actual logic of our native methods, usually coded in C or C++.
JNI header file – this header file for C/C++ (include/jni.h into the JDK directory)
includes all definitions of JNI elements that we may use into our native programs.
C/C++ Compiler – we can choose between GCC, Clang, Visual Studio, or any
other we like as far as it's able to generate a native shared library for our platform.
“native” keyword – as we've already covered, any method marked as native must
be implemented in a native, shared lib.
System.loadLibrary(String libname) – a static method that loads a shared library
from the file system into memory and makes its exported functions available for
our Java code.
static {
System.loadLibrary("native");
}
// Declare a native method sayHello() that receives no arguments and returns void
private native void sayHello();
}
As we can see, we load the shared library in a static block. This ensures that it will be
ready when we need it and from wherever we need it.
Alternatively, in this trivial program, we could instead load the library just before calling
our native method because we're not using the native library anywhere else.