jna.loadLibrary не может найти собственный файл библиотеки - PullRequest
0 голосов
/ 26 марта 2020

Я создал собственный jar с родной библиотечной оболочкой. Структура получившегося файла jar:

library.jar
 |- com (there are my .java classes)
 |- libs (there is the native - libmylib.so)
 |- META-INF

Я загружаю нативную библиотеку следующим образом:

MyLibClass instance = (MyLibClass) Native.loadLibrary("mylib", MyLibClass.class);

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

Exception in thread "main" java.lang.UnsatisfiedLinkError: Unable to load library 'mylib':
libmylib.so: cannot open shared object file: No such file or directory

Как мне решить эту проблему?

Ответы [ 2 ]

1 голос
/ 26 марта 2020

Как отмечено на странице JNA Getting Started ,

Сделайте вашу целевую библиотеку доступной для вашей программы Java. Есть несколько способов сделать это:

  • Предпочтительный метод - установить системное свойство jna.library.path для пути к вашей целевой библиотеке. Это свойство похоже на java.library.path, но применяется только к библиотекам, загруженным JNA.
  • Измените соответствующую переменную среды доступа к библиотекам перед запуском ВМ. Это PATH в Windows, LD_LIBRARY_PATH в Linux и DYLD_LIBRARY_PATH в OSX.
  • Сделайте вашу собственную библиотеку доступной на вашем пути к классам, по пути {OS}-{ARCH}/{LIBRARY}, где {OS}-{ARCH} является каноническим префиксом JNA для нативных библиотек (например, win32-x86, linux-amd64 или darwin). Если ресурс находится внутри файла JAR, он будет автоматически извлечен при загрузке.
0 голосов
/ 28 марта 2020

Я сделал это, используя stati c Класс Loader следующим образом:

static class Loader {

    private Loader() {
    }

    static String getNative() {
        InputStream in = null;
        FileOutputStream fos = null;
        File fileOut = null;
        System.setProperty("jna.library.path",
                System.getProperty("java.io.tmpdir"));

        in = Loader.class.getResourceAsStream(
                        "/libs/libmylib.so");

        if (in != null) {
            try {
                fileOut = File.createTempFile("mylib", ".so");
                fileOut.deleteOnExit();

                fos = new FileOutputStream(fileOut);

                int count;
                byte[] buf = new byte[1024];

                while ((count = in.read(buf, 0, buf.length)) > 0) {
                    fos.write(buf, 0, count);
                }

            } catch (IOException ex) {
                throw new Error("Failed to create temporary file: " + ex);
            } finally {
                try {
                    in.close();
                } catch (IOException ex) {
                }

                if (fos != null) {
                    try {
                        fos.close();
                    } catch (IOException ex) {
                    }
                }

                return fileOut.getAbsolutePath();
            }
        } else {
            throw new Error("Couldn't open native library file");
        }
    }
}

Там я загружаю библиотечный файл из ресурсов и копирую его содержимое во временный каталог. Как вы можете видеть перед этим, я установил jna.library.path во временную папку, поэтому JNA будет искать там библиотеки.

Далее я загружаю библиотеку так:

MyLibClass instance = (MyLibClass) Native.loadLibrary(Loader.getNative(), MyLibClass.class);
...