Проблемы загрузки .so файл с JNA в Spring Boot на Linux - PullRequest
1 голос
/ 25 апреля 2019

У меня есть приложение, написанное на Java с Spring Boot. Это приложение должно загружать .so файлы, которые связаны с проектом, я использую JNA для этого. Однако загрузчик JNA, похоже, не может подобрать файлы .so, и приложение не запускается.

Я попытался запустить приложение из IntelliJ и запустив упакованный .jar с "java -jar". .So файлы пока хранятся в src / main / resources / linux-x86-64. Я попытался сохранить их в другом каталоге, например, src / main / resources / libs / linux-x86-64 и установить свойство "jna.library.path", но JNA все равно не может найти файлы.

Это журнал отладки для JNA:

Trying (via loadLibrary) jnidispatch
Looking in classpath from sun.misc.Launcher$AppClassLoader@18b4aac2 for /com/sun/jna/linux-x86-64/libjnidispatch.so
Found library resource at jar:file:/home/dalivi/.m2/repository/net/java/dev/jna/jna/4.5.0/jna-4.5.0.jar!/com/sun/jna/linux-x86-64/libjnidispatch.so
Trying /tmp/jna--1339148563/jna4246531844315283838.tmp
Found jnidispatch at /tmp/jna--1339148563/jna4246531844315283838.tmp
Looking for library 'GTransTF'
Adding paths from jna.library.path: null
Trying libGTransTF.so
Adding system paths: [/usr/lib/x86_64-linux-gnu, /lib/x86_64-linux-gnu, /lib64, /usr/lib, /lib, /lib/i386-linux-gnu, /usr/lib/i386-linux-gnu, /usr/lib/x86_64-linux-gnu/libfakeroot]
Trying libGTransTF.so
Looking for version variants
Looking in classpath from sun.misc.Launcher$AppClassLoader@18b4aac2 for GTransTF
Found library resource at file:/home/dalivi/Workspace/java/geotransboot/target/classes/linux-x86-64/libGTransTF.so
Looking in /home/dalivi/Workspace/java/geotransboot/target/classes/linux-x86-64/libGTransTF.so
2019-04-25 12:43:38.032 ERROR 25897 --- [o-auto-1-exec-1] s.l.g.c.TransformationRestController     : Handler dispatch failed; nested exception is java.lang.UnsatisfiedLinkError: libCoreGTrans.so: cannot open shared object file: No such file or directory

Кажется, я нахожу один из файлов в каталоге: libGTransTF.so , но затем немедленно завершается ошибкой при попытке найти файл libCoreGTrans.so , который присутствует в тот же каталог, что и предыдущий файл.

Я должен отметить, что в Windows это работает просто отлично. JNA находит соответствующие dll-файлы в каталоге, указанном в «jna.library.path».

1 Ответ

4 голосов
/ 25 апреля 2019

Поведение Windows заключается в поиске зависимых библиотек в каталоге, из которого происходит .dll, поэтому, когда jna загружает библиотеку в память, оттуда также загружается зависимая библиотека.

Если вы запустите окно терминала и перейдете в каталог, в котором существует .so, и выполните команду:

ldd ./libGTransTF.so

и это означает, что она не может найти библиотеку libCoreGTrans.so, тогда вы можете видеть, что порядок поиска не найдет это местоположение.

Загрузчик ссылок во время выполнения (ld.so) использует набор решений о том, где искать библиотеки. Поведение по умолчанию не включает каталог, в котором была найдена библиотека.

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

-Wl,-rpath,'$ORIGIN'

к строке ссылки. Он должен заполняться константным значением $ORIGIN, иначе это не сработает, так что это может быть немного сложно сделать правильно в make-файле. Это значение, которое разрешается во время выполнения.

Это все очень хорошо и хорошо, если вы собираете библиотеку самостоятельно, но если вы получаете библиотеки откуда-то еще или уже собрали их и не хотите восстанавливать их, вы можете использовать инструмент, такой как patchelf, чтобы отредактировать путь поиска для .so, чтобы добавить его исходное местоположение:

patchelf --set-rpath '$ORIGIN' libGTransTF.so

Затем, когда вы запустите:

ldd ./libGTransTF.so

он сможет успешно найти библиотеку libCoreGTrans.so.

...