Загрузка файла Linux .so во время выполнения Java

#java #dynamic-linking

#java #динамическое связывание

Вопрос:

Я пытаюсь загрузить файл linux .so во время выполнения на Java, но получаю сообщение UnsatisfiedLinkError. Я передаю аргумент виртуальной машины -Djava.library.path=/Users/tom/codebase/ jni / dist при запуске приведенного ниже java main из моего Test.class . В libSample.so файл находится в каталоге /Users/tom/codebase/jni/dist. Есть идеи? Спасибо!

 public class Test {

    public static void main(String[] args) {
        System.out.println(System.getProperty("java.library.path")); 
                //prints /Users/tom/codebase/jni/dist
        System.loadLibrary("Sample");
    }

}
  

Аргумент виртуальной машины:

 -Djava.library.path=/Users/tom/codebase/jni/dist
  

Исключение:

 Exception in thread "main" java.lang.UnsatisfiedLinkError: no Sample in java.library.path
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1758)
at java.lang.Runtime.loadLibrary0(Runtime.java:823)
at java.lang.System.loadLibrary(System.java:1045)
at Test.main(Test.java:9)
  

Я также попытался использовать прямой подход (используя System.load) и получил приведенные ниже результаты, если они помогают какому-либо исключению в потоке «main» java.lang.Ошибка неудовлетворительной ссылки: /Users/tom/codebase/jni/dist/libSample.so: подходящее изображение не найдено. Нашел: /Users/tom/codebase/jni/dist/libCiscoEnergyWiseJni.итак: неизвестный тип файла, первые восемь байтов: 0x7F 0x45 0x4C 0x46 0x01 0x01 0x01 0x00

Комментарии:

1. Зависит ли ваша библиотека от другой библиотеки под названием libCiscoEnergyWiseJni?

2. (если это так, вам нужно добавить:/the/folder/where/its/installed в конец java.library.path)

3. нет, извините, это была опечатка … исправлена

4. Я сталкиваюсь с точно такой же проблемой. Смогли ли вы найти решение?

Ответ №1:

Библиотеки в Linux часто именуются по шаблону libXXX.so , и я считаю, что Java следует этому соглашению. System.loadLibrary("Sample") Возможно, вы ищете libSample.so So. Вы можете убедиться в этом, создав быструю тестовую программу для вызова System.mapLibraryName и проверив выходные данные.

Чтобы устранить проблему, предполагая, что это на самом деле проблема, с которой вы столкнулись, вы можете либо переименовать файл вашей библиотеки, либо использовать System.load (не System.loadLibrary ), который загрузит библиотеку, указанную с точным именем файла, которое вы ей передаете, без каких-либо преобразований. Однако последний метод не переносим на разные платформы.

Комментарии:

1. Спасибо за ответ, Дэвид. Имя файла на самом деле libSample.so Я отредактировал свой первый вопрос … извините за путаницу

2. Я попробовал прямой подход (используя System.load) и получил приведенные ниже результаты, если они помогают какому-либо исключению в потоке «main» java.lang. Ошибка неудовлетворительной ссылки: /Users/tom/codebase/jni/dist/libSample.so: подходящее изображение не найдено. Найдено: /Users/tom/codebase/jni / dist/libCiscoEnergyWiseJni.so: неизвестный тип файла, первые восемь байтов: 0x7F 0x45 0x4C 0x46 0x01 0x01 0x01 0x00

3. @c12: Я предлагаю отредактировать эту информацию в вопросе для других участников ответа.

4. СПАСИБО, действительно, спустя 2 часа и 10 сообщений я нашел решение. Префикс «libXXX».

Ответ №2:

Попробуйте использовать

 Runtime.getRuntime().load(resource);
  

Ответ №3:

Я столкнулся с той же проблемой в Linux и решил ее, установив LD_LIBRARY_PATH переменную

 export LD_LIBRARY_PATH=<Lib File Path>:$LD_LIBRARY_PATH.
  

Надеюсь, это поможет

Ответ №4:

 public class Demo 
{
    static
    {
        try 
        {
            System.load("/home/libsofile.so");
        }
        catch (UnsatisfiedLinkError e) 
        {
            System.err.println("Native code library failed to load.n"   e);
            System.exit(1);
        }
    }
}