Java - JNA и общие библиотеки, UnsatisfiedLinkError при запуске из .jar в Linux - PullRequest
1 голос
/ 14 мая 2011

[Окончательное решение можно найти в комментариях к принятому ответу. Благодаря bmargulies]

Эй, народ,

У меня довольно странная ошибка, и я не могу понять причину. Итак, вот настройка: я создаю независимый от платформы музыкальный проигрыватель на Java. В качестве встроенной звуковой библиотеки я использую движок irrKlang (http://www.ambiera.com/irrklang/), который поставляется в виде набора общих библиотек для Windows, Linux и MacOS соответственно. Поскольку эти библиотеки написаны на C ++, я создал общую библиотеку в качестве оболочки (также на C ++, но с использованием extern "C" и т. Д.), Также скомпилированной для каждой необходимой операционной системы. Теперь я использую эту оболочку из JNA. Я использую eclipse, все необходимые библиотеки resist в главной папке проекта (текущий рабочий каталог). Теперь возникает проблема: все работает нормально, если я запускаю свое Java-приложение из затмения и даже встраиваю .jar под Windows в основную папку проекта, и его выполнение там не вызывает проблем. Но конкретно в Linux, когда я упаковываю (обычно работающее!) Приложение в .jar, я получаю следующую ошибку:

Exception in thread "main" java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:616)
at org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader.main(JarRsrcLoader.java:58)
Caused by: java.lang.UnsatisfiedLinkError: Unable to load library 'IrrklangWrapper': libIrrKlang.so: cannot open shared object file: No such file or directory
at com.sun.jna.NativeLibrary.loadLibrary(NativeLibrary.java:163)
at com.sun.jna.NativeLibrary.getInstance(NativeLibrary.java:236)
at com.sun.jna.Library$Handler.<init>(Library.java:140)
at com.sun.jna.Native.loadLibrary(Native.java:379)
at com.sun.jna.Native.loadLibrary(Native.java:364)
at Demo.<init>(Demo.java:29)
at Demo.main(Demo.java:55)
... 5 more

"IrrKlangWrapper" - это моя собственная общая библиотека, "libIrrKlang.so" - это библиотека, обернутая ею. Таким образом, JNA может найти мою библиотеку, но моя библиотека не может найти упакованную. Weird! Тем более, что этого не произойдет, если я начну проект напрямую (без создания .jar).

Поскольку некоторые из вас могут попросить об этом, здесь также код, написанный на C ++ - хотя я не думаю, что источник проблемы находится там, поскольку ошибка возникает до вызова содержащегося в нем метода:

#include <iostream>
#include <stdio.h>
#include <irrKlang.h>
#include <sys/stat.h>
#include <string>
#include <unistd.h>
using namespace std;

extern "C" {

int func(char *path) {
    cout << path << endl;

    irrklang::ISoundEngine* engine = irrklang::createIrrKlangDevice();
    engine->loadPlugins("./");
    cout << engine->getDriverName() << endl;
    engine->play2D(path);
    //Endless loop for testing. TODO: Remove
    while (true) {
    }
    engine->drop();

    return 0;
}
}

Кто-нибудь понял, как это решить? Поскольку мое приложение должно быть независимым от платформы, я не могу копировать какие-либо общие библиотеки в определенные папки - они должны находиться в (под) папке моего приложения.

Заранее спасибо,

Андре

1 Ответ

3 голосов
/ 14 мая 2011

В Linux вам нужно установить LD_LIBRARY_PATH, чтобы включить каталог, содержащий эту вторую общую библиотеку.

Это требование очень сложно обойти. LD_LIBRARY_PATH читается только ld.so в начале процесса Java. Вы не можете добавить к этому позже.

Вы должны сделать одну большую общую библиотеку, что означает поиск версий .a ваших зависимостей для включения в нее.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...