UnsatisfiedLinkError, когда System.load-зависимые библиотеки в обратном порядке - PullRequest
0 голосов
/ 14 ноября 2018

У меня есть динамическая библиотека libjvm_host.so, которая зависит от libsgx_uae_service_sim.so и 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)

Обе эти зависимости находятся рядом с libjvm_host.so, причина, по которой он говорит not found, заключается в том, что я не установил LD_LIBRARY_PATH.

Я пытаюсь использовать System.load для загрузки этих библиотек, используя их абсолютные пути, не полагаясь на LD_LIBRARY_PATH, в обратном порядке:

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 - вот где я распаковал .so с. Однако я получаю 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)

Он загружает первые два .so с и не работает на libjvm_host.so, что зависит от первых двух.

В нескольких местах я читал, что это способ загрузки библиотек, которые зависят друг от друга, не полагаясь на LD_LIBRARY_PATH, однако я не могу заставить его работать. Чего мне не хватает?

1 Ответ

0 голосов
/ 27 ноября 2018

Решено это альтернативным способом. Не уверен, почему обратная загрузка не работает, но следующее работает:

При связывании верхнего уровня .so добавьте RPATH $ORIGIN примерно так:

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

С CMake:

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

Этот специальный RPATH заставляет загрузчик добавить родительский каталог верхнего уровня .so в список путей к библиотекам, то есть достаточно иметь зависимости в той же папке, что и libjvm_host.so.

С этим System.load(File(temporaryDirectory, "libjvm_host.so").absolutePath само по себе работает как шарм.

...