Sunday, June 22, 2008

Intro to JNI on Linux

Today (as the title says) I'm going to go over a few things dealing with JNI compilation for Linux. I recommend you read my previous post for JNI on Windows if you've never used it before, this just deals with the quick and dirty details.

Let's get to some simple code:

myNativeMethod.cpp:

#include "myClass.h"

JNIEXPORT void JNICALL Java_myClass_myNativeMethod(JNIEnv *env, jobject obj){
printf("well hello there!\n");
}



Easy stuff. As always, myClass.h is generated after the java code is compiled and run through javah. Our native method is defined in the java source as:


...
private native void myNativeMethod();
static {
System.loadLibrary("myNativeLibrary");
}
...


NOTE: System.loadLibrary expects a certain filename. On Linux, it prepends "lib" and appends ".so" - so the above call looks for "libmyNativeLibrary.so" on Linux, just as it would look for "myNativeLibrary.dll" on Windows.

Let's compile! Of course, your include paths will probably be different, but that shouldn't be hard to fix.


g++ -shared -o libmyNativeLibrary.so -I/usr/lib/jvm/java-6-sun-1.6.0.00/include/ -I/usr/lib/jvm/java-6-sun-1.6.0.00/include/linux myNativeMethod.cpp


Viola! We have compiled our library.

Now, when you try to use it, sometimes you'll get am UnsatisfiedLinkError if everything's not exactly right. This is caused from a couple things:

1) You didn't name it lib[name].so!
2) You didn't use the right method signature - the header signature and your own signature should be EXACTLY the same.
3) It's simply not in Java's library search path. The quick and dirty way to force it in is to run:

java -Djava.library.path=./ myClass

Unfortunately, the library path that overwrites usually has stuff in it that is needed - which results in more Unsatisfied Link Errors. The next quick and dirty way is to just move libmyNativeLibrary.so to /lib or somewhere else in the library path.

Gatta run, I may add more later.

No comments: