While porting OpenJDK8 to Optware-ng, I have encountered an issue of
compiled java being unable to load libjava.so. With JamVM the output is
this:
[root@unknown bin]$ java -version
Error initialising natives: couldn't open
libjava.so: use -verbose:jni for
more information
Error initialising VM (initialiseNatives)
Error: Could not create the Java Virtual Machine.
Error: A fatal exception has occurred. Program will exit.
[root@unknown bin]$ java -verbose:jni -version
[Failed to open library /opt/lib/jvm/openjdk8/jre/lib/arm/libjava.so: File
not found]
Error initialising natives: couldn't open libjava.so: use -verbose:jni for
more information
Error initialising VM (initialiseNatives)
Error: Could not create the Java Virtual Machine.
Error: A fatal exception has occurred. Program will exit.
With Hotspot Zero VM it looked a bit different, but was the same issue:
dlopen() failed when trying to load libjava.so. With glibc, it was fine.
After googling a bit, I discovered that this may be the case of unsatisfied
dependencies, however java was compiled with relative RPATH entries
(containing $ORIGIN) that pointed to the needed libs:
[root@unknown bin]$ readelf -d java
Dynamic section at offset 0x788 contains 29 entries:
Tag Type Name/Value
0x00000001 (NEEDED) Shared library: [libm.so.1]
0x00000001 (NEEDED) Shared library: [libdl.so.1]
0x00000001 (NEEDED) Shared library: [libiconv.so.2]
0x00000001 (NEEDED) Shared library: [libpthread.so.1]
0x00000001 (NEEDED) Shared library: [libz.so.1]
0x00000001 (NEEDED) Shared library: [libjli.so]
0x00000001 (NEEDED) Shared library: [libc.so.1]
0x0000000e (SONAME) Library soname: [lib.so]
0x0000000f (RPATH) Library rpath:
[/opt/lib:$ORIGIN/../lib/arm/jli:$ORIGIN/../lib/arm]
...
I then compiled with additional absolute RPATH entries, which pointed to
the relevant libraries:
[root@unknown bin]$ readelf -d java
Dynamic section at offset 0x788 contains 29 entries:
Tag Type Name/Value
0x00000001 (NEEDED) Shared library: [libm.so.1]
0x00000001 (NEEDED) Shared library: [libdl.so.1]
0x00000001 (NEEDED) Shared library: [libiconv.so.2]
0x00000001 (NEEDED) Shared library: [libpthread.so.1]
0x00000001 (NEEDED) Shared library: [libz.so.1]
0x00000001 (NEEDED) Shared library: [libjli.so]
0x00000001 (NEEDED) Shared library: [libc.so.1]
0x0000000e (SONAME) Library soname: [lib.so]
0x0000000f (RPATH) Library rpath:
[/opt/lib/jvm/openjdk8/jre/lib/arm/jli:/opt/lib/jvm/openjdk8/jre/lib/arm:/opt/lib:$ORIGIN/../lib/arm/jli:$ORIGIN/../lib/arm]
...
And, java took off:
[root@unknown bin]$ java -version
openjdk version "1.8.0_60-Optware-ng"
OpenJDK Runtime Environment (build 1.8.0_60-Optware-ng-b24)
JamVM (build 2.0.0, inline-threaded interpreter with stack-caching)
I've experienced this kind of behavior with JamVM and Hotspot Zero VM on
ARMv7 and MIPSEL archs with uclibc-ng-1.0.6. It worked OK with glibc, so
I'm guessing this is a uclibc-ng issue. Maybe, something wrong with the way
dlopen() function deals with RPATH entries that contain $ORIGIN.
--
Best regards,
Alex Potapenko