Для System.loadLibrary()
работы библиотека (в Windows, DLL) должна находиться в каталоге где-то у вас PATH
или по пути, указанному в java.library.path
системном свойстве (чтобы вы могли запускать Java как java -Djava.library.path=/path/to/dir
).
Кроме того, для loadLibrary()
вы указываете базовое имя библиотеки без .dll
символа в конце. Итак, для /path/to/something.dll
вы просто использовали бы System.loadLibrary("something")
.
Вам также нужно смотреть на то, UnsatisfiedLinkError
что вы получаете. Если там написано что-то вроде:
Exception in thread "main" java.lang.UnsatisfiedLinkError: no foo in java.library.path
то он не может найти библиотеку foo (foo.dll) в вашем PATH
или java.library.path
. Если там написано что-то вроде:
Exception in thread "main" java.lang.UnsatisfiedLinkError: com.example.program.ClassName.foo()V
тогда что-то не так с самой библиотекой в том смысле, что Java не может сопоставить родную функцию Java в вашем приложении с ее фактическим родным аналогом.
Для начала я бы добавил немного времени в журнал вашего System.loadLibrary()
звонка, чтобы увидеть, правильно ли он выполняется. Если он вызывает исключение или не находится в пути кода, который фактически выполняется, вы всегда будете получать последний тип, UnsatisfiedLinkError
описанный выше.
Кстати, большинство людей помещают свои loadLibrary()
вызовы в блок статического инициализатора в классе с собственными методами, чтобы гарантировать, что он всегда выполняется ровно один раз:
class Foo {
static {
System.loadLibrary('foo');
}
public Foo() {
}
}
loadLibrary()
примечания - очень полезно, когда вы не знаете, что делаете не так.lib
префикс. ТакSystem.loadLibrary("foo")
нужноlibfoo.so
.blah.jnilib
и Linuxlibblah.so
. Итак, два часа спустя, после многочисленных попыток, я пришел к выводу, что OSX также требуетlib
префиксаМенять переменную java.library.path во время выполнения недостаточно, потому что она читается JVM только один раз. Вы должны сбросить его, например:
System.setProperty("java.library.path", path); //set sys_paths to null final Field sysPathsField = ClassLoader.class.getDeclaredField("sys_paths"); sysPathsField.setAccessible(true); sysPathsField.set(null, null);
Пожалуйста, возьмите добычу по адресу: Изменение пути к библиотеке Java во время выполнения .
источник
Исходный ответ Адама Баткина приведет вас к решению, но если вы повторно развернете свое веб-приложение (без перезапуска веб-контейнера), вы должны столкнуться со следующей ошибкой:
java.lang.UnsatisfiedLinkError: Native Library "foo" already loaded in another classloader at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1715) at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1646) at java.lang.Runtime.load0(Runtime.java:787) at java.lang.System.load(System.java:1022)
Это происходит потому, что ClassLoader, который изначально загрузил вашу DLL, по-прежнему ссылается на эту DLL. Однако ваше веб-приложение теперь работает с новым ClassLoader, и поскольку работает та же самая JVM, а JVM не допускает двух ссылок на одну и ту же DLL, вы не можете перезагрузить ее. Таким образом, ваше веб-приложение не может получить доступ к существующей DLL и не может загрузить новую. Итак .... вы застряли.
Документация Tomcat ClassLoader объясняет, почему ваше перезагруженное веб-приложение работает в новом изолированном ClassLoader и как можно обойти это ограничение (на очень высоком уровне).
Решение состоит в том, чтобы немного расширить решение Адама Баткина:
package awesome; public class Foo { static { System.loadLibrary('foo'); } // required to work with JDK 6 and JDK 7 public static void main(String[] args) { } }
Затем поместите банку, содержащую ТОЛЬКО этот скомпилированный класс, в папку TOMCAT_HOME / lib.
Теперь в вашем веб-приложении вам просто нужно заставить Tomcat ссылаться на этот класс, что можно сделать так просто:
Class.forName("awesome.Foo");
Теперь ваша DLL должна быть загружена в общий загрузчик классов, и на нее можно ссылаться из вашего веб-приложения даже после повторного развертывания.
Есть смысл?
Рабочую справочную копию можно найти в коде Google, static-dll-bootstrapper .
источник
Вы можете использовать,
System.load()
чтобы указать абсолютный путь, который вам нужен, а не файл в папке стандартной библиотеки для соответствующей ОС.Если вам нужны уже существующие собственные приложения, используйте
System.loadLibrary(String filename)
. Если вы хотите предоставить свой собственный, вам, вероятно, лучше использовать load ().Вы также должны быть в состоянии использовать
loadLibrary
сjava.library.path
набором правильно. См.ClassLoader.java
Источник реализации, показывающий оба проверяемых пути (OpenJDK)источник
В случае, когда проблема заключается в том, что System.loadLibrary не может найти рассматриваемую DLL, одно распространенное заблуждение (подкрепленное сообщением об ошибке Java) заключается в том, что ответом является системное свойство java.library.path. Если вы установите системное свойство java.library.path на каталог, в котором находится ваша DLL, то System.loadLibrary действительно найдет вашу DLL. Однако, если ваша DLL, в свою очередь, зависит от других DLL, как это часто бывает, то java.library.path не может помочь, потому что загрузкой зависимых DLL полностью управляет операционная система, которая ничего не знает о java.library. путь. Таким образом, почти всегда лучше обойти java.library.path и просто добавить каталог вашей DLL в LD_LIBRARY_PATH (Linux), DYLD_LIBRARY_PATH (MacOS) или Path (Windows) до запуска JVM.
(Примечание: я использую термин «DLL» в общем смысле DLL или разделяемой библиотеки.)
источник
Если вам нужно загрузить файл, относящийся к некоторому каталогу, в котором вы уже находитесь (например, в текущем каталоге), вот простое решение:
File f; if (System.getProperty("sun.arch.data.model").equals("32")) { // 32-bit JVM f = new File("mylibfile32.so"); } else { // 64-bit JVM f = new File("mylibfile64.so"); } System.load(f.getAbsolutePath());
источник
Для тех, кто ищет
java.lang.UnsatisfiedLinkError: no pdf_java in java.library.path
Я столкнулся с тем же исключением; Я перепробовал все, и важные вещи, чтобы заставить его работать:
Он работал с tomcat 6.
источник
Если вы считаете, что добавили путь к собственной библиотеке
%PATH%
, попробуйте выполнить тестирование с помощью:System.out.println(System.getProperty("java.library.path"))
Он должен показать вам, действительно ли ваша DLL включена
%PATH%
%PATH%
источник
Бедный я! потратил на это целый день. Пишу здесь, если кто-то повторяет эту проблему.
Я пытался загрузить, как предлагал Адам, но затем попался с исключением AMD64 vs IA 32. Если в любом случае после работы в соответствии с пошаговым руководством Адама (без сомнения, лучший выбор), попробуйте установить 64-разрядную версию последней jre. ваши JRE и JDK являются 64-битными, и вы правильно добавили его в свой путь к классам.
Вот мой рабочий пример: неудовлетворенная ошибка ссылки
источник
Для Windows я обнаружил, что когда я загружал файлы (вызовы jd2xsx.dll и ftd2xx.dll) в папку windowws / system32, это решало проблемы. Затем у меня возникла проблема с моей новой fd2xx.dll, связанной с параметрами, поэтому мне пришлось загрузить старую версию этой dll. Мне придется это вынести позже.
Примечание: jd2xsx.dll вызывает ftd2xx.dll, поэтому установка пути для jd2xx.dll может не сработать.
источник
Я использую Mac OS X Yosemite и Netbeans 8.02, у меня такая же ошибка, и я нашел простое решение, подобное приведенному выше, это полезно, когда вам нужно включить в проект собственную библиотеку. Итак, сделайте следующее для Netbeans:
1.- Right click on the Project 2.- Properties 3.- Click on RUN 4.- VM Options: java -Djava.library.path="your_path" 5.- for example in my case: java -Djava.library.path=</Users/Lexynux/NetBeansProjects/NAO/libs> 6.- Ok
Надеюсь, это может быть кому-то полезно. Ссылка, по которой я нашел решение, находится здесь: java.library.path - что это такое и как использовать
источник
VM Options: java -Djava.library.path="your_path"
У меня была такая же проблема, и ошибка была связана с переименованием библиотеки DLL. Может случиться так, что имя библиотеки также написано где-то внутри dll. Когда я вернул его исходное имя, я смог загрузить, используя
System.loadLibrary
источник
Это просто, просто напишите java -XshowSettings: properties в командной строке в Windows, а затем вставьте все файлы в путь, указанный в java.library.path.
источник
Во-первых, вам нужно убедиться, что каталог вашей собственной библиотеки находится в каталоге
java.library.path
. Посмотрите, как это сделать здесь . Затем вы можете позвонитьSystem.loadLibrary(nativeLibraryNameWithoutExtension)
- убедитесь, что расширение файла не включено в имя вашей библиотеки.источник