This sample program is meant to call a native
method written in C.
Java Code
class HelloWorld {
private native voi
Try this,
HelloWorld.c
#include "HelloWorld.h"
#include <stdio.h>
JNIEXPORT void JNICALL Java_HelloWorld_print(JNIEnv *env, jobject obj)
{
printf("Hello World!\n");
return;
}
Compile it using cl.exe (I'm using VC++ and CL.EXE required following command line switches.)
c:\>cl -c /I"c:\Program Files\java\jdk1.7.0\include" /I"c:\Prog ram Files\java\jdk1.7.0\include\win32" HelloWorld.c
Link .obj module
c:\>link /libpath="c:\Program Files\java\jdk1.7.0\lib" HelloWorld.obj /dll
You should include the following header file in your native code first
#include <jni.h>
In my case in UNIX system,
This header file jni.h
is present at /usr/lib/jvm/java-8-openjdk-amd64/include/
Also, jni_md.h
is present at /usr/lib/jvm/java-8-openjdk-amd64/include/linux
You can get the path to above files if you know where the Java installation path redirects you in your system. Get it done by following set of commands.
whereis java
/usr/bin/java /usr/share/java /usr/share/man/man1/java.1.gz
ls -l /usr/bin/java
/usr/bin/java -> /etc/alternatives/java
ls -l /etc/alternatives/java
/etc/alternatives/java -> /usr/lib/jvm/java-8-openjdk-amd64/jre/bin/java
where (->) is symbolic link.
/usr/lib/jvm/java-8-openjdk-amd64/jre/bin/java
Also don't forget to include
jni.h
&jni_md.h
files path while doing their native Compilation.
Compilation:-
gcc -I /usr/lib/jvm/java-8-openjdk-amd64/include/ -I /usr/lib/jvm/java-8-openjdk-amd64/include/linux/ -o libHelloWorld.so -shared *nativeSourceCodeFile*.c
where (-I) is Identify the Path.
jni.h
is provided in reference.jni.h
does the explicit import of jni_md.h
ie. #include "jni_md.h"
& that's why we've provided next reference in our compilation to that jni_md.h
file.jni_md.h
contains the machine-dependent typedefs for jbyte, jint and jlong.Execution:-
java -Djava.library.path=. HelloWorld
Next,
JNIEXPORT void JNICALL Java_HelloWorld_print( JNIEnv* env , jobject obj){
printf("Hello World!\n");
}
Just see the small changes made and try to implement it.
I suspect that jni.h
is trying to #include <jni_md.h>
, which is then failing because you haven't added its location to your include path.
Try adding both of these entries to your C compiler's include path:
C:\Program Files\Java\jdk1.7.0\include
C:\Program Files\Java\jdk1.7.0\include\win32
The win32
path might not be necessary, depending on how jni.h
is set up.
I had this issue once, my solution was actually to edit the jni.h's internal #include from
"jni_md.h"
to "win32/jni_md.h"
, although there is probably a less hacky way you are supposed to do it.
A Simple Java Native Interface (JNI) example in Java
// Main.java
public class Main {
public native int intMethod(int i);
static {
System.loadLibrary("Main");
}
public static void main(String[] args) {
System.out.println(new Main().intMethod(2));
}
}
// Main.c:
#include "Main.h"
JNIEXPORT jint JNICALL Java_Main_intMethod(
JNIEnv *env, jobject obj, jint i)
{
return i * i;
}
Compile and run:
javac Main.java -h .
gcc -dynamiclib -O3 \
-I/usr/include \
-I$JAVA_HOME/include \
-I$JAVA_HOME/include/darwin \
Main.c -o libMain.dylib
java -cp . -Djava.library.path=$(pwd) Main
Output:
4