简体   繁体   中英

UnsatisfiedLinkError when System.load-ing dependent libraries in reverse order

I have a dynamic library libjvm_host.so which depends on libsgx_uae_service_sim.so and libsgx_urts_sim.so :

$ ldd libjvm_host.so 
linux-vdso.so.1 =>  (0x00007ffcc376f000)
libsgx_uae_service_sim.so => not found
libsgx_urts_sim.so => not found
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f37d91fc000)
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f37d8e7a000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f37d8c64000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f37d889a000)
/lib64/ld-linux-x86-64.so.2 (0x00007f37d9651000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f37d8591000)

Both of these dependencies are next to libjvm_host.so , the reason it says not found is because I haven't set LD_LIBRARY_PATH .

I'm trying to use System.load to load these libraries using their absolute paths, without relying on LD_LIBRARY_PATH , in reverse order:

System.load(File(temporaryDirectory, "libsgx_uae_service_sim.so").absolutePath)
System.load(File(temporaryDirectory, "libsgx_urts_sim.so").absolutePath)
System.load(File(temporaryDirectory, "libjvm_host.so").absolutePath)

temporaryDirectory is where I unpacked the .so s. However I'm getting an UnsatisfiedLinkError :

java.lang.UnsatisfiedLinkError: /tmp/com.r3.sgx.host-libraries/libjvm_host.so: libsgx_uae_service_sim.so: cannot open shared object file: No such file or directory
    at java.lang.ClassLoader$NativeLibrary.load(Native Method)
    at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1941)
    at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1824)
    at java.lang.Runtime.load0(Runtime.java:809)
    at java.lang.System.load(System.java:1086)
    at com.r3.sgx.core.host.internal.NativeLoader.loadHostLibraries(NativeLoader.kt:31)

It loads the first two .so s, and fails on libjvm_host.so , which depends on the former two.

I've read in multiple places that this is the way to load libraries that depend on one another without relying on LD_LIBRARY_PATH , however I can't get it to work. What am I missing?

Solved this in an alternative way. Not sure why the reverse loading doesn't work, but the following does:

When linking the top-level .so add an RPATH of $ORIGIN like so:

ld (...) -rpath "\$ORIGIN"

With CMake:

target_link_libraries(jvm_host
    (...)
    -Wl,-rpath,"$ORIGIN")

This special RPATH causes the loader to add the top-level .so's parent directory to the list of library paths, meaning it's enough to have the dependencies in the same folder as libjvm_host.so .

With this System.load(File(temporaryDirectory, "libjvm_host.so").absolutePath on its own works like a charm.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM