Как исправить UnsatisfiedLinkError (Не удается найти зависимые библиотеки) в проекте JNI - PullRequest
73 голосов
/ 23 мая 2011

Я работаю над проектом Java, который использует JNI. JNI вызывает пользовательскую библиотеку, которую я написал сам, скажем, mylib.dll, и это зависит от сторонней библиотеки, libsndfile-1.dll.

Когда я запускаю свою программу, она вылетает с

java.lang.UnsatisfiedLinkError:  C:\...path...\mylib.dll: Can't find dependent libraries.

Я искал этот сайт (и другие) и попробовал несколько исправлений:

  1. Я запустил обходчик зависимостей. DW дал пару предупреждений - что две библиотеки, необходимые для libsndfile, MPR.DLL и SHLWAPI.DLL, имели «неразрешенный импорт» - но в DW FAQ сказано, что эти предупреждения можно безопасно игнорировать.

  2. Я исправил имена методов в mylib.dll, как предлагалось здесь . Имена методов каким-то образом были искажены компилятором, но я добавил флаги компоновщика, и теперь имена методов dll точно совпадают с именами в моем заголовочном файле jni.

  3. Я поместил все эти библиотеки DLL в один и тот же каталог - в тот же каталог, что и .jar, который их вызывает, - чтобы убедиться, что они находятся на правильном пути.

Без кубиков.

Кто-нибудь знает, что происходит?

Я занимаюсь разработкой в ​​Visual Studio 2010 на MacBook Pro (через Parallels). Я провожу тестирование в Windows XP на ноутбуке Toshiba.

Ответы [ 13 ]

44 голосов
/ 23 мая 2011

Я почти уверен, что путь к классам и путь поиска в общей библиотеке имеют мало общего друг с другом. Согласно Книге JNI (которая по общему признанию устарела), в Windows, если вы не используете системное свойство java.library.path, DLL должна находиться в текущем рабочем каталоге или в каталоге, указанном в Windows PATH переменная окружения.


Обновление:

Похоже, Oracle удалила PDF со своего веб-сайта. Я обновил ссылку выше, чтобы указать на экземпляр PDF, живущий в Техасском университете - Арлингтон.

Также вы можете прочитать HTML-версию Oracle спецификации JNI . Он находится в разделе «Java 8» на веб-сайте Java и, надеюсь, будет еще какое-то время.


Обновление 2:

По крайней мере, в Java 8 (я не проверял более ранние версии) вы можете сделать:

java -XshowSettings:properties -version

для поиска пути поиска в общей библиотеке. Найдите значение свойства java.library.path в этом выводе.

17 голосов
/ 11 мая 2012

Хочу сообщить об этом интересном случае, после того, как перепробовал весь вышеописанный метод, ошибка все еще есть. Странная вещь, это работает на компьютере с Windows 7, но на Windows XP это не так. Затем я использую средство обхода зависимостей и обнаружил, что в Windows XP нет VC ++ Runtime, как моего требования к DLL. После установки VC ++ Runtime пакета здесь он работает как шарм. Что меня беспокоило, так это то, что он говорит «Не могу найти зависимые библиотеки», хотя интуитивно существует зависимая от JNI библиотека DLL, однако в конечном итоге выясняется, что зависимая библиотека JNI требует другого зависимого библиотеки DLL. Надеюсь, это поможет.

13 голосов
/ 07 августа 2014

Вам нужно загрузить библиотеку JNI.

System.loadLibrary загружает DLL из пути JVM (путь бина JDK).

Если вы хотите загрузить явный файл с путем, используйте System.load ()

См. Также: Разница между System.load () и System.loadLibrary в Java

5 голосов
/ 29 апреля 2013

Пожалуйста, убедитесь, что ваш путь к библиотеке правильный или нет. Конечно, вы можете использовать следующий код для проверки пути к вашей библиотеке: System.out.println(System.getProperty("java.library.path"));

Вы можете назначить java.library.path при запуске приложения Java:

java -Djava.library.path=path ...
4 голосов
/ 06 октября 2012

При установке javacv и opencv в сочетании с Eclipse была идентичная проблема с машиной XP. Оказалось, что мне не хватало следующих файлов:

  • msvcp100.dll
  • msvcr100.dll

Как только они были установлены, проект компилировался и работал нормально.

3 голосов
/ 09 сентября 2014

Если вы загрузите 32-битную версию вашего dll с 64-битным JRE, у вас может возникнуть эта проблема.Это был мой случай.

2 голосов
/ 14 мая 2018

Я нашел замечательную статью от друзей на keepafe, в которой рассказывалось то же, что и я.Это сработало для меня, так что, надеюсь, это поможет вам!Прочитайте, если вам интересно ( Опасность загрузки собственных библиотек на Android ) или просто используйте

compile 'com.getkeepsafe.relinker:relinker:1.2.3'

и замените

System.loadLibrary("myLibrary");

с

ReLinker.loadLibrary(context, "mylibrary");
2 голосов
/ 30 октября 2017
  • Краткий ответ: для ошибки «не удается найти зависимую библиотеку» проверьте свой $ PATH (соответствует пункту № 3 ниже)
  • Длинный ответ:
    1. Чистая Javaworld: jvm использует «Classpath» для поиска файлов классов
    2. JNI world (java / native border): jvm использует «java.library.path» (по умолчанию $ PATH) для поиска dll
    3. чистый родной мир: нативный код использует $ PATH для загрузки других библиотек
1 голос
/ 29 июня 2016

В моей ситуации я пытался запустить веб-сервис Java в Tomcat 7 через соединитель в Eclipse. Приложение работало хорошо, когда я развернул файл war на экземпляре Tomcat 7 на своем ноутбуке. Приложению требуется драйвер jdbc типа 2 для "IBM DB2 9.5". По какой-то странной причине соединитель в Eclispe не смог увидеть или использовать пути в переменных среды IBM DB2 для доступа к файлам dll, установленным на моем ноутбуке в качестве клиента jcc. В сообщении об ошибке указывалось, что не удалось найти файл db2jcct2 dll или не удалось найти зависимые библиотеки для этого файла dll. В итоге я удалил разъем и перестроил его. Тогда это работало правильно. Я добавляю это решение здесь как документацию, потому что я не смог найти это конкретное решение где-либо еще.

1 голос
/ 03 октября 2015

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

SET PATH = "/ cygdrive / c / Program Files / Java / jdk1.8.0_45";% PATH%

...