Как исправить UnsatisfiedLinkError (не удается найти зависимые библиотеки) в проекте JNI

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

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

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

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

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

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

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

Нет кубиков.

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

Я делаю свое развитие в Visual Studio 2010 на MacBook pro (через Parallels). Я делаю свое тестирование в Windows XP на ноутбуке toshiba.

Ответ 1

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


Update:

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

Кроме того, вы также можете прочитать версию Oracle HTML Спецификация JNI. Это живет в разделе Java 8 на веб-сайте Java и, надеюсь, будет некоторое время.


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

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

java -XshowSettings:properties -version

чтобы найти путь поиска совместно используемой библиотеки. Посмотрите на значение свойства java.library.path в этом выпуске.

Ответ 2

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

Ответ 4

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

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

java -Djava.library.path=path ...

Ответ 5

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

  • msvcp100.dll
  • msvcr100.dll

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

Ответ 6

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

Ответ 7

  • Короткий ответ: для ошибки "невозможно найти зависимую библиотеку", проверьте свой $PATH (соответствует пункту № 3 пули ниже)
  • Длинный ответ:
    • Pure java world: jvm использует "Classpath" для поиска файлов классов.
    • Мир JNI (java/родная граница): jvm использует "java.library.path" (который по умолчанию равен $PATH) для поиска dlls
    • чистый родной мир: собственный код использует $PATH для загрузки других dll

Ответ 8

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

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

и заменить

System.loadLibrary("myLibrary");

с

ReLinker.loadLibrary(context, "mylibrary");

Ответ 9

У меня была точно такая же проблема, и, наконец, она была решена.

Я поместил все зависимые DLL в ту же папку, где был сохранен mylib.dll, и убедитесь, что JAVA Compiler смог его найти (если в пути компиляции нет mylib.dll, будет ошибка, сообщающая об этом во время компиляции). Важно отметить, что вы должны убедиться, что все зависимые библиотеки имеют одну и ту же версию с mylib.dll, например, если ваша версия mylib.dll является версией, тогда вы также должны поместить в нее версию всех зависимых библиотек,

Надеюсь, это поможет другим, кто столкнулся с одной и той же проблемой.

Ответ 10

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

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

Ответ 11

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

Ответ 12

Создание статической библиотеки работало для меня, компиляция с использованием g++ -static. Он связывает зависимые библиотеки вместе со сборкой.

Ответ 13

  • Перейдите в http://tess4j.sourceforge.net/usage.html и нажмите Visual C++ Redistributable for VS2012
  • Загрузите его и запустите VSU_4\vcredist_x64.exe или VSU_4\vcredist_x84.exe в зависимости от конфигурации вашей системы.
  • Поместите ваши файлы dll в папку lib вместе с вашими другими библиотеками (например, \lib\win32-x86\your dll files).