
Signature
[ don't email me support questions or followups ]
g o r d o n + n e w s @ b a l d e r 1 3 . s e
>> When Java is started with
>>
[quoted text clipped - 14 lines]
>
> What mechanism do you use to load the library in your code?
System.loadLibrary(String)
> When you tested the various ways of specifying the library location,
> did you leave the library in the same place the whole time?
Yes.
> Does the library have dependencies on other dynamic libraries?
> ("readelf -d libFoo.so", look for NEEDED entries, or ldd -v).
libc.so.6 (found in /lib/tls), nothing else.
> Does setting e.g. LD_DEBUG=libs tell you anything?
Not really; all I can see is that the libraries loaded at Java startup
(e.g. libpthread.so.0) are located in a different way than the libraries
loaded from Java.
The former produces several messages like
trying file=./libpthread.so.0
while the latter does not output a 'trying' at all, it just says
calling init: /home/laurenz/jni/libTest.so
or nothing at all, depending on whether I set LD_LIBRARY_PATH or not.
> Finally, please post the complete text of the error message. There is
> likely something we're both overlooking.
I will, and I also will post the complete sample, as it is very short.
The problem occurs not only with this test program (so it is no bug of the
test program).
I have searched java.sun.com and elsewhere, but didn't find any clue.
I wonder if it is a bug or 'expected behaviour'.
Thanks for any hints,
Laurenz Albe
Error message:
==============
Exception in thread "main" java.lang.UnsatisfiedLinkError: no Test in
java.library.path
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1517)
at java.lang.Runtime.loadLibrary0(Runtime.java:788)
at java.lang.System.loadLibrary(System.java:834)
at Test.<clinit>(Test.java:7)
Java source (Test.java):
========================
public class Test {
static {
System.loadLibrary("Test");
}
public static native void main(String[] args);
}
Compiled with:
==============
javac -g Test.java
Native method source (Test.c):
==============================
#include <jni.h>
JNIEXPORT void JNICALL Java_Test_main
(JNIEnv *a, jclass b, jobjectArray c) {
}
Compiled with:
==============
gcc -Wall -o libTest.so -shared -Wl,-soname,libTest.so Test.c -static -lc
Gordon Beaton - 03 Aug 2006 14:52 GMT
> I have searched java.sun.com and elsewhere, but didn't find any
> clue. I wonder if it is a bug or 'expected behaviour'.
Until now I thought that it was possible to load native libraries in
Java using ld.so, i.e. without setting LD_LIBRARY_PATH or
java.library.path.
But after looking (rather cursively) at the J2SE sources it seems that
Java needs to be able to find the actual file based on the contents of
java.library.path (in turn derived from LD_LIBRARY_PATH), before
passing the resulting absolute path to a native method that loads the
library. This is unfortunate and IMO unnecessary, since dlopen() will
search ld.so.cache if not given an absolute path.
On the other hand if your library has dependencies on other shared
libraries, those additional libraries must be loaded by ld.so, so the
"normal" rules apply: put the path in ld.so.conf or LD_LIBRARY_PATH,
i.e. java.library.path is not sufficient.
/gordon

Signature
[ don't email me support questions or followups ]
g o r d o n + n e w s @ b a l d e r 1 3 . s e
Laurenz Albe - 03 Aug 2006 15:47 GMT
> Until now I thought that it was possible to load native libraries in
> Java using ld.so, i.e. without setting LD_LIBRARY_PATH or
[quoted text clipped - 11 lines]
> "normal" rules apply: put the path in ld.so.conf or LD_LIBRARY_PATH,
> i.e. java.library.path is not sufficient.
Thank you for looking into that, your explanation seems reasonable
and would explain the behaviour.
I agree that this behaviour is unfortunate, because it breaks expected
behaviour on Linux.
Yours,
Laurenz Albe