Я работаю над проектом Java, который использует JNI. JNI вызывает пользовательскую библиотеку, которую я написал сам, скажем, mylib.dll, которая зависит от сторонней библиотеки libsndfile-1.dll.
Когда я запускаю свою программу, она вылетает с
java.lang.UnsatisfiedLinkError: C:\...path...\mylib.dll: Can't find dependent libraries.
Я искал этот сайт (и другие) и попробовал несколько исправлений:
Я запустил dependency walker. DW выдал пару предупреждений - что две библиотеки, требуемые libsndfile, MPR.DLL и SHLWAPI.DLL, имеют «неразрешенный импорт», но в DW FAQ сказано, что эти предупреждения можно безопасно игнорировать.
Я исправил имена методов в mylib.dll, как было предложено здесь . Имена методов каким-то образом были искажены компилятором, но я добавил флаги компоновщика, и теперь имена методов dll в точности совпадают с именами в моем заголовочном файле jni.
Я помещаю все эти DLL в один и тот же каталог - в тот же каталог, что и вызывающий их .jar - чтобы убедиться, что они находятся в правильном ПУТИ.
Никаких кубиков.
Кто-нибудь знает, что происходит?
Я занимаюсь разработкой в Visual Studio 2010 на MacBook Pro (через Parallels). Тестирую в Windows XP на ноутбуке toshiba.
Ответы:
Я почти уверен, что путь к классам и путь поиска разделяемой библиотеки мало связаны друг с другом. Согласно книге JNI (которая, по общему признанию, устарела), в Windows, если вы не используете
java.library.path
системное свойство, DLL должна находиться в текущем рабочем каталоге или в каталоге, указанном вPATH
переменной среды Windows .Обновить:
Похоже, Oracle удалила PDF-файл со своего веб-сайта. Я обновил ссылку выше, чтобы указать на экземпляр PDF-файла из Техасского университета в Арлингтоне.
Также вы можете прочитать HTML-версию спецификации JNI от Oracle . Он находится в разделе Java 8 на веб-сайте Java и, надеюсь, будет там какое-то время.
Обновление 2:
По крайней мере, в Java 8 (я не проверял более ранние версии) вы можете:
чтобы найти путь поиска в общей библиотеке. Найдите значение
java.library.path
свойства в этих выходных данных.источник
CLASSPATH
совсем не используется. Я тоже не уверен, что онcwd
вообще используется.java.library.path
или простоPATH
будет работать. @dB ', то место, где вы их сейчас разместили, неправильное .Я хочу сообщить об этом интересном случае, после того, как попробовал все вышеперечисленные методы, ошибка все еще существует. Странно то, что он работает на компьютере с Windows 7, а на Windows XP - нет. Затем я использую обходчик зависимостей и обнаружил, что в Windows XP нет VC ++ Runtime как моего требования к dll. После установки пакета VC ++ Runtime здесь он работает как шарм. Что меня беспокоило, так это то, что он продолжает говорить: «Не могу найти зависимые библиотеки», хотя интуитивно зависимая dll от JNI присутствует, однако, наконец, оказывается, что для зависимой от JNI dll требуется другая зависимая dl. Надеюсь, это поможет.
источник
Вам необходимо загрузить вашу библиотеку JNI.
System.loadLibrary загружает DLL из пути JVM (путь к контейнеру JDK).
Если вы хотите загрузить явный файл с путем, используйте System.load ()
См. Также: Разница между System.load () и System.loadLibrary в Java
источник
Убедитесь, что путь к вашей библиотеке правильный или нет. Конечно, вы можете использовать следующий код, чтобы проверить путь к вашей библиотеке:
System.out.println(System.getProperty("java.library.path"));
Вы можете указать путь java.library.path при запуске приложения Java:
источник
Если вы загружаете 32-битную версию своей DLL с 64-битной JRE, у вас может быть эта проблема. Это был мой случай.
источник
chromedriver.exe
драйвер Selenium для Chrome, который, насколько я могу судить, поставляется только в 32-битной версии.Была такая же проблема с машиной XP при установке
javacv
иopencv
в сочетании с Eclipse. Оказалось, что мне не хватало следующих файлов:После их установки проект компилировался и работал нормально.
источник
источник
Я нашел отличную статью некоторых друзей в keepafe, в которой повторилось то же самое, что и я. У меня это сработало, так что, надеюсь, это поможет и вам! Прочтите, если вам интересно ( Опасности загрузки собственных библиотек на Android ), или просто используйте
compile 'com.getkeepsafe.relinker:relinker:1.2.3'
и заменить
System.loadLibrary("myLibrary");
с участием
ReLinker.loadLibrary(context, "mylibrary");
источник
Раньше у меня была точно такая же проблема, и наконец ее решили.
Я поместил все зависимые библиотеки DLL в ту же папку, где хранился mylib.dll, и убедился, что компилятор JAVA может найти его (если в пути компиляции нет mylib.dll, во время компиляции будет сообщение об ошибке). Важно отметить, что вы должны убедиться, что все зависимые библиотеки имеют одну и ту же версию с mylib.dll, например, если ваш mylib.dll является версией выпуска, вы также должны поместить туда версию выпуска всех зависимых библиотек. .
Надеюсь, это поможет другим, кто столкнулся с той же проблемой.
источник
У меня была такая же проблема, и я попробовал все, что написано здесь, чтобы исправить это, но у меня ничего не сработало. В моем случае я использую Cygwin для компиляции dll. Кажется, что JVM пытается найти библиотеки DLL JRE в виртуальном пути Cygwin. Я добавил путь виртуального каталога Cygwin к библиотекам DLL JRE, и теперь он работает. Я сделал что-то вроде:
источник
В моей ситуации я пытался запустить веб-службу java в Tomcat 7 через коннектор в Eclipse. Приложение работало нормально, когда я развернул файл войны на экземпляре Tomcat 7 на моем ноутбуке. Приложению требуется драйвер jdbc типа 2 для «IBM DB2 9.5». По какой-то странной причине коннектор в Eclispe не мог видеть или использовать пути в переменных среды IBM DB2 для доступа к файлам dll, установленным на моем ноутбуке в качестве клиента jcc. В сообщении об ошибке либо говорилось, что не удалось найти файл db2jcct2 dll, либо не удалось найти зависимые библиотеки для этого файла dll. В конце концов, я удалил соединитель и восстановил его. Тогда все заработало нормально. Я добавляю это решение в качестве документации, потому что мне не удалось найти это конкретное решение где-либо еще.
источник
У меня сработало создание статической библиотеки, компиляция с использованием
g++ -static
. Он связывает зависимые библиотеки вместе со сборкой.источник
установка распространяемого пакета Microsoft Visual C ++ 2010 SP1 Исправлено
источник
поместите необходимые dll в папку и установите путь к папке в переменной среды PATH. убедитесь, что отражена обновленная переменная PATH среды.
источник
Я столкнулся с той же проблемой с библиотекой ffmpeg после объединения двух проектов Android в один проект.
На самом деле проблема возникла из-за двух разных версий библиотеки ffmpeg, но они были загружены в память с одинаковыми именами. Одна библиотека была помещена в JNiLibs, а другая - внутри другой библиотеки, используемой в качестве модуля. Мне не удалось изменить код модуля, поскольку он был доступен только для чтения, поэтому я переименовал тот, который использовался в моем собственном коде, в ffmpegCamera и загрузил его в память с тем же именем.
System.loadLibrary("ffmpegCamera");
Это устранило проблему, и теперь обе версии библиотек загружаются в память с отдельным именем и идентификатором процесса.
источник
При вызове
System.loadLibrary()
JVM будет искатьjava.library.path
вашу собственную библиотеку. Однако, если эта собственная библиотека объявляет какие-либо зависимости от других собственных библиотек, то операционной системе будет поручено найти эти зависимости от собственных библиотек.Поскольку операционная система не имеет понятия об этом
java.library.path
, она не увидит никаких каталогов, которые вы разместите в java.library.path. Вместо этого он будет искать только каталоги в переменной среды PATH операционной системы. Это совершенно нормально, если зависимость собственной библиотеки является собственной библиотекой операционной системы, потому что она будет найдена в PATH. Однако, если зависимость собственной библиотеки является собственной библиотекой, созданной вами или кем-то еще, она не будет найдена в PATH, если вы не поместите ее туда. Такое поведение является странным, неожиданным и плохо документированным, но оно задокументировано в системе отслеживания проблем OpenJDK здесь . Вы также можете найти еще один ответ StackOverflow, подкрепляющий это объяснение, здесь .Итак, у вас есть несколько вариантов. Вы можете либо загрузить каждую собственную библиотеку в правильном порядке зависимостей с помощью
System.loadLibrary()
, либо изменить PATH, включив в него каталоги, в которых хранятся ваши собственные библиотеки.источник
Visual C++ Redistributable for VS2012
VSU_4\vcredist_x64.exe
или вVSU_4\vcredist_x84.exe
зависимости от конфигурации вашей системыdll
файлы вlib
папку вместе с другими библиотеками (например\lib\win32-x86\your dll files
).источник