Today I would like share my very first experience about JNI—Java Native Interface. The Java Native Interface (JNI) is a programming framework that enables Java code running in a Java Virtual Machine (JVM) to call and be called by native applications and libraries written in other languages such as C, C++ and assembly. This post uses a Hello-world example to demonstrate the communication between Java and C on Mac OS X.
Create a Java Application
Firstly, create a Java application called App.java
:
Note that: shared library hello is loaded during class initialization; method
sayHello
is native, so its behavior is unknown during the compilation phase,
and only be defined in runtime. Now compile the Java file:
$ javac App.java
Generate Header File via javah
Generate a header file for C/C++ programs by running the javah
utility on the
class file:
$ javah App
And then a file called App.h
is generated:
As you can see, the method generated is called Java_App_sayHello
, composed by
language “Java”, class name “App”, and method name “sayHello”.
Create Implementation in C
Implement the say-hello solution in language C as following:
The solution includes the header file of JNI jni.h
, the header file of
standard input/output stdio.h
, and the header file of the hello-world
application App.h
. The method signature matches the one in header file,
generated by javah
utility. And we are simply adding a pring function inside
the method.
Compile the Implementation
Now the implementation is done. We need to compile it using GCC in two steps:
First step, compile the file App.c
, and the output file is App.o
. In the
following command, the 1st flag -I
includes the folder $JAVA_HOME/include
where jni.h
is stored, and the 2nd flag -I
includes the OS X folder
$JAVA_HOME/include/darwin
where jni_md.h
is stored (used by jni.h
). And
the output file is called App.o
.
$ gcc -c -I "/Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home/include" -I "/Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home/include/darwin" App.c
Second step, link the output file App.o
to shared library libhello.jnilib
:
$ gcc -shared -o libhello.jnilib App.o
Run the Program
Now, everything is ready. Run the JNI program:
$ java App -Djava.library.path=.
Hello JNI.
And it works :)