0% found this document useful (0 votes)
11 views

Java Native Interface Notes

Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
11 views

Java Native Interface Notes

Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 4

JAVA NATIVE INTERFACE

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.

Need to use native code:

 The need to handle some hardware


 Performance improvement for a very demanding process
 An existing library that we want to reuse instead of rewriting it in Java.

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.

Native Methods: The JVM Meets Compiled Code


Java provides the native keyword that's used to indicate that the method implementation will
be provided by a native code.
Normally, when making a native executable program, we can choose to use static or shared
libs:

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

JNI Elements In Code (Java And C/C++)


Java elements:

 “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.

C/C++ elements (many of them defined within jni.h)


 JNIEXPORT- marks the function into the shared lib as exportable so it will be
included in the function table, and thus JNI can find it
 JNICALL – combined with JNIEXPORT, it ensures that our methods are available
for the JNI framework
 JNIEnv – a structure containing methods that we can use our native code to access
Java elements
 JavaVM – a structure that lets us manipulate a running JVM (or even start a new
one) adding threads to it, destroying it, etc…

First JNI program by implementing a class “Hello World”.


To begin, we create the following Java class that includes the native method that will
perform the work:
package com.baeldung.jni;

public class HelloWorldJNI {

static {
System.loadLibrary("native");
}

public static void main(String[] args) {


new HelloWorldJNI().sayHello();
}

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

Implementing a Method in C++


Now, we need to create the implementation of our native method in C++.
Within C++ the definition and the implementation are usually stored in .h and .cpp files
respectively.
First, to create the definition of the method, we have to use the -h flag of the Java
compiler:
1 javac -h . HelloWorldJNI.java
This will generate a com_baeldung_jni_HelloWorldJNI.h file with all the native methods
included in the class passed as a parameter, in this case, only one:
1 JNIEXPORT void JNICALL Java_com_baeldung_jni_HelloWorldJNI_sayHello
2 (JNIEnv *, jobject);
As we can see, the function name is automatically generated using the fully qualified
package, class and method name.
Also, something interesting that we can notice is that we're getting two parameters passed
to our function; a pointer to the current JNIEnv; and also the Java object that the method
is attached to, the instance of our HelloWorldJNI class.
Now, we have to create a new .cpp file for the implementation of
the sayHello function. This is where we'll perform actions that print “Hello World”
to console.
We'll name our .cpp file with the same name as the .h one containing the header and add
this code to implement the native function:
1 JNIEXPORT void JNICALL Java_com_baeldung_jni_HelloWorldJNI_sayHello
2 (JNIEnv* env, jobject thisObject) {
3 std::cout << "Hello from C++ !!" << std::endl;
}
4

Compiling And Linking


At this point, we have all parts we need in place and have a connection between
them.
We need to build our shared library from the C++ code and run it!
To do so, we have to use G++ compiler, not forgetting to include the JNI headers from
our Java JDK installation.
Once we have the code compiled for our platform. we have to include it in a new shared
library.

You might also like