I was asked questions similar to the following one quite a few times recently:
[weiqi@gao] $ java Main
Exception in thread "main" java.lang.UnsatisfiedLinkError: no Foo in java.librar
y.path
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1682)
at java.lang.Runtime.loadLibrary0(Runtime.java:823)
at java.lang.System.loadLibrary(System.java:1030)
at Foo.(Foo.java:3)
at Main.main(Main.java:3)
This question is most prone to be asked by C++ programmers working in a hybrid C++/JNI/Java environment, usually prefixed with "I'm trying to run our test suite, but am getting the following error. Any ideas?"
Here's my response in a email yesterday, posted here through the "Pull email response up to blog entry" refactoring pattern (the answer is Linux specific, but can be translated to other OSes with minimal effort):
This is the part that trips up people all the time. Look at it this way:
Your Main class uses the Foo class
The Foo class uses the libFoo.so JNI glue library. Foo probably looks like this:
public class Foo {
static {
System.loadLibrary("Foo");
}
// ...
}
The libFoo.so JNI glue library uses underlying C++ *.so libraries
The manner through which java searches for the needed files are different in each scenario:
Java searches for *.class files through the "-cp"/"-classpath" command line switch. If neither are specified on the command line, $CLASSPATH is searched
Java searches for JNI glue *.so files through the "-Djava.library.path" command line switch. If "-Djava.library.path" is not specified, $LD_LIBRARY_PATH is searched, but the /etc/ld.so.conf mechanism is not used
The way a JNI glue library searches for the underlying C++ *.so libraries is not controlled by the Java process at all. This is just a case where one *.so library is linked to other *.so libraries. The normal operating system rules apply ($LD_LIBRARY_PATH, /etc/ld.so.conf, etc.)
So you need "-Djava.library.path=...:/path/to/dir-of-libFoo:..." on your java command line. Or add /path/to/dir-of-libFoo to your $LD_LIBRARY_PATH.
As you can see, it's quite a long winded explanation (like a lot of things Java). And even this is not the most thorough. The key insight is the jump from the highlighted part of the stack trace to the corresponding conclusion #2.