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.
Hi Alex, Alex Potapenko wrote,
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.
I have only experience with Java7. But there you need these symbols activated in uClibc-ng: LDSO_RUNPATH=y LDSO_RUNPATH_OF_EXECUTABLE=y
Do you have both enabled? I think the latter is the most important part for Java. $ORIGIN works fine in uClibc-ng. I have added support for it a while ago from some patches lying around since years. You better update to 1.0.9 as it contains some serious bugfixes.
best regards Waldemar