Ява.ленг.UnsatisfiedLinkError no *****.dll в java.библиотека.путь
как я могу загрузить пользовательский dll-файл в моем веб-приложении? Я пробовал следующие способы, но его провал.
- скопировал все необходимые DLL в
system32
папка и попытался загрузить один из них вServlet
конструкторSystem.loadLibrary
- скопированы необходимые DLL в
tomcat_home/shared/lib
иtomcat_home/common/lib
- все эти DLL находятся в
WEB-INF/lib
веб-приложения
12 ответов:
для того чтобы
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.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() { } }
оригинальный ответ Адама Баткина приведет вас к решению, но если вы повторно развернете свое веб-приложение (без перезапуска веб-контейнера), вы должны столкнуться со следующей ошибкой:
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)
это происходит потому, что загрузчик классов, который первоначально загрузил вашу DLL, все еще ссылается на эту DLL. Однако теперь ваше веб-приложение работает с новым загрузчиком классов, и поскольку одна и та же JVM работает, а JVM не разрешает 2 ссылки на одну и ту же DLL, вы не можете перезагрузка его. Таким образом, ваше веб-приложение не может получить доступ к существующей DLL и не может загрузить новую. Так.... ты застрял.
документация загрузчика классов Tomcat описывает, почему ваш перезагруженный веб-приложение работает в новом изолированном загрузчике классов и как вы можете обойти это ограничение (на очень высоком уровне).
решение состоит в том, чтобы немного расширить решение Адама Баткина:
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 должна быть загружена в общий загрузчик классов, и на нее можно ссылаться из вашего веб-приложения даже после повторного развертывания.
смысл?
рабочей копии можно найти на GitHub, static-dll-bootstrapper .
изменение ' java.библиотека.переменной 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 во время выполнения.
можно использовать
System.load()
обеспечить абсолютный путь, который является то, что вы хотите, а не файл в стандартной папке библиотека для соответствующей ОС.если вы хотите собственные приложения, которые уже существуют, используйте
System.loadLibrary(String filename)
. Если вы хотите предоставить свой собственный вы, вероятно, лучше с нагрузкой().вы также должны быть в состоянии использовать
loadLibrary
Сjava.library.path
установлен правильно. СмотритеClassLoader.java
для источника реализации, показывающего оба пути проверено (слепых)
в случае, когда проблема заключается в том, что система.loadLibrary не может найти DLL, о которой идет речь, одно распространенное заблуждение (усиленное сообщением об ошибке Java) заключается в том, что системное свойство java.библиотека.путь-это ответ. Если задано системное свойство java.библиотека.путь к каталогу, в котором находится ваша библиотека DLL, а затем система.loadLibrary действительно найдет вашу DLL. Однако, если ваша DLL в свою очередь зависит от других DLL, как это часто бывает, то java.библиотека.путь не может помочь, потому что нагрузка из зависимых DLL управляется полностью операционной системой, которая ничего не знает о java.библиотека.путь. Таким образом, почти всегда лучше обходить java.библиотека.путь и просто добавить директорию в DLL путь LD_LIBRARY_PATH (Линукс), DYLD_LIBRARY_PATH (для macOS), или пути (для Windows) перед запуском виртуальной машины.
(Примечание: я использую термин "DLL" в общем смысле DLL или общей библиотеки.)
для тех, кто ищет
java.lang.UnsatisfiedLinkError: no pdf_java in java.library.path
я столкнулся с тем же исключением; я пробовал все и важные вещи, чтобы заставить его работать:
- правильная версия PDF lib.jar (в моем случае это была неправильная версия jar, хранящаяся в серверной среде выполнения )
- создайте папку и сохраните в ней pdflib jar и добавьте папку в переменную PATH
он работал с tomcat 6.
плохо мне ! провел за этим целый день.Запишите его здесь, если какой-либо орган повторяет эту проблему.
Я пытался загрузить, как предложил Адам, но затем был пойман с исключением AMD64 vs IA 32.Если в любом случае после работы в соответствии с пошаговым руководством Adam(без сомнения,лучший выбор), попробуйте иметь 64-разрядную версию последней версии jre.Убедитесь, что ваши JRE и JDK являются 64-разрядными, и вы правильно добавили их в свой путь к классам.
мой рабочий пример идет здесь: неудовлетворенная ссылка ошибка
Если вам нужно загрузить файл, который относится к некоторому каталогу, где вы уже находитесь (например, в текущем каталоге), вот простое решение:
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());
для windows я обнаружил, что когда я загрузил filles(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.библиотека.путь-что это такое и как им пользоваться
У меня была та же проблема, и ошибка была вызвана переименованием dll. Может случиться так, что имя библиотеки также написано где-то внутри dll. Когда я вернул свое первоначальное имя, я смог загрузить с помощью
System.loadLibrary
This is My java.library.path: java.library.path = C:\Program Files\Java\jdk1.7.0_51\bin C:\WINDOWS\Sun\Java\bin C:\WINDOWS\system32 C:\WINDOWS C:\WINDOWS\system32 C:\Program Files\I.R.I.S. SA\iDRS_15_2_for_Win64_15_2_11_1717\lib\idrskr .lib C:\Program Files\I.R.I.S. SA\iDRS_15_2_for_Win64_15_2_11_1717\bin\iDRMSG idgeDll.dll C:\Program Files\I.R.I.S. SA\iDRS_15_2_for_Win64_15_2_11_1717\bin\iDRMSG aderDll.dll C:\Program Files\Java\jdk1.7.0_51\bin C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\include C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\lib C:\WINDOWS\System32\Wbem C:\WINDOWS\System32\WindowsPowerShell\v1.0 C:\Program Files (x86)\Microsoft SQL Server0\Tools\Binn\ C:\Program Files\Microsoft SQL Server0\DTS\Binn Still rror comes: infile >> D:\pdf_upload\pre_idrs15_win_temporary_license_activation_tutorial.pdf outFile >> D:\pdf_upload\processed\pre_idrs15_win_temporary_license_activation_tutorial.txt Hello : This is java library path:(NICKRJ) C:\Program Files\Java\jdk1.7.0_51\bin;C:\WINDOWS\Sun\Java\bin;C:\WINDOWS\system32;C:\WINDOWS;C:/Program Files/Java/jdk1.7.0_51/jre/bin/server;C:/Program Files/Java/jdk1.7.0_51/jre/bin;C:/Program Files/Java/jdk1.7.0_51/jre/lib/amd64;C:\WINDOWS\system32;C:\Program Files\I.R.I.S. SA\iDRS_15_2_for_Win64_15_2_11_1717\lib\idrskrn15.lib;C:\Program Files\I.R.I.S. SA\iDRS_15_2_for_Win64_15_2_11_1717\bin\iDRMSGEBridgeDll.dll;C:\Program Files\I.R.I.S. SA\iDRS_15_2_for_Win64_15_2_11_1717\bin\iDRMSGEReaderDll.dll;C:\Program Files\Java\jdk1.7.0_51\bin;C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\include;C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\lib;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0;C:\Program Files (x86)\Microsoft SQL Server0\Tools\Binn\;C:\Program Files\Microsoft SQL Server0\DTS\Binn;D:\WorkSet\New folder\eclipse_kepler\eclipse;;. Exception in thread "main" java.lang.UnsatisfiedLinkError: no iDRMSGEBridgeDll in java.library.path at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1886) at java.lang.Runtime.loadLibrary0(Runtime.java:849) at java.lang.System.loadLibrary(System.java:1088) at com.bi.iDRMSGEBridgeDll.callOcr(iDRMSGEBridgeDll.java:78) at com.bi.iDRMSGEBridgeDll.main(iDRMSGEBridgeDll.java:15) Here is my Java JNI class: package com.bi; import org.omg.PortableInterceptor.SYSTEM_EXCEPTION; public class iDRMSGEBridgeDll { public native int iDRMSGEDll_Initialize(String strPropertiesFileName); public native int iDRMSGEDll_VerifyLicense(); public native int iDRMSGEDll_ConvertFile(String strSourceFileName, String srcOutputFileName, String formatType); public native int iDRMSGEDll_Finalize(); public static void main(String[] args) { //iDRMSGEBridgeDll.callOcr("bgimage.jpg","jpg","","d:\","d:\","4"); iDRMSGEBridgeDll.callOcr("pre_idrs15_win_temporary_license_activation_tutorial.pdf","pdf","","D:\pdf_upload","D:\pdf_upload\processed","4"); /* System.loadLibrary("iDRMSGEBridgeDll"); iDRMSGEBridgeDll obj = new iDRMSGEBridgeDll(); if ( obj.iDRMSGEDll_Initialize("D:\iris\iDRSGEDll.properties") != 0 ) { obj.iDRMSGEDll_Finalize(); return; } System.out.println("iDRMSGEDll_Initialize success."); if ( obj.iDRMSGEDll_VerifyLicense() != 0 ) { obj.iDRMSGEDll_Finalize(); return; } System.out.println("iDRMSGEDll_VerifyLicense success."); if (obj.iDRMSGEDll_ConvertFile("E:\UI changes File_by Shakti\PDF\S14-005_FRAMEWORK_AGREEMENT_FOR_ENGINE_MAINTENANCE_SERVICES_EASYJET[1].pdf", "E:\SK_Converted_Files\MVP_CONTRACTS\Southwest CFM56-7\S14-005_FRAMEWORK_AGREEMENT_FOR_ENGINE_MAINTENANCE_SERVICES_EASYJET[1]\S14-005_FRAMEWORK_AGREEMENT_FOR_ENGINE_MAINTENANCE_SERVICES_EASYJET[1].txt", "4" ) != 0 ) { obj.iDRMSGEDll_Finalize(); return; } System.out.println("iDRMSGEDll_ConvertFile 1 success."); /*if (obj.iDRMSGEDll_ConvertFile("C:\Software\iDRS_15_1_7_2304\sample_pdfs\scan1_200dpi.pdf", "C:\Software\iDRS_15_1_7_2304\sample_pdfs\scan1_200dpi.out", 4) != 0 ) { obj.iDRMSGEDll_Finalize(); return; } System.out.println("iDRMSGEDll_ConvertFile 2 success."); if (obj.iDRMSGEDll_ConvertFile("C:\Software\iDRS_15_1_7_2304\sample_pdfs\scan1_300dpi.pdf", "C:\Software\iDRS_15_1_7_2304\sample_pdfs\scan1_300dpi.out", 4) != 0 ) { obj.iDRMSGEDll_Finalize(); return; } System.out.println("iDRMSGEDll_ConvertFile 3 success."); if (obj.iDRMSGEDll_ConvertFile("C:\Software\iDRS_15_1_7_2304\sample_pdfs\scan2_300dpi.pdf", "C:\Software\iDRS_15_1_7_2304\sample_pdfs\scan2_300dpi.out", 4) != 0 ) { obj.iDRMSGEDll_Finalize(); return; } System.out.println("iDRMSGEDll_ConvertFile 4 success."); obj.iDRMSGEDll_Finalize(); System.out.println("iDRMSGEDll_Finalize success."); return;*/ } public static String callOcr(String inputFile, String docType, String engineType, String filePath,String outputFolder,String type) throws RuntimeException { String message = ""; String formatType = type; String inFile = filePath +"\" +inputFile; String outFile=""; if(type.equals("4")) outFile = outputFolder +"\"+inputFile.substring(0,inputFile.lastIndexOf("."))+".txt"; else if(type.equals("6")) outFile = outputFolder +"\"+inputFile.substring(0,inputFile.lastIndexOf("."))+".rtf"; else if(type.equals("9")) outFile = outputFolder +"\"+inputFile.substring(0,inputFile.lastIndexOf("."))+".pdf"; else outFile = outputFolder +"\"+inputFile.substring(0,inputFile.lastIndexOf("."))+".csv"; System.out.println("infile >> "+inFile); System.out.println("outFile >> "+outFile); System.out.println("Hello : This is java library path:(NICKRJ) " +System.getProperty("java.library.path")); System.loadLibrary("iDRMSGEBridgeDll"); //System.load("C:\Program Files (x86)\I.R.I.S. SA\iDRS_15_2_for_Win64_15_2_11_1717\bin\iDRMSGEBridgeDll.dll"); //Runtime.getRuntime().loadLibrary("iDRMSGEBridgeDll"); iDRMSGEBridgeDll obj = new iDRMSGEBridgeDll(); try { if ( obj.iDRMSGEDll_Initialize("D:\IRIS\iDRSGEDll.properties") != 0 ) { obj.iDRMSGEDll_Finalize(); // return ; } System.out.println("iDRMSGEDll_Initialize success."); if ( obj.iDRMSGEDll_VerifyLicense() != 0 ) { obj.iDRMSGEDll_Finalize(); // return; } System.out.println("iDRMSGEDll_VerifyLicense success."); // formatType= JOptionPane.showInputDialog("Please input mark format type: "); if (formatType!=null && formatType.equals("4")) { obj.iDRMSGEDll_ConvertFile(inFile, outFile, "4" ); obj.iDRMSGEDll_Finalize(); // return; } else if(formatType!=null && formatType.equals("6")) { obj.iDRMSGEDll_ConvertFile(inFile, outFile, "6" ); obj.iDRMSGEDll_Finalize(); // return; } else if(formatType!=null && formatType.equals("7")) { obj.iDRMSGEDll_ConvertFile(inFile, outFile, "7" ); obj.iDRMSGEDll_Finalize(); // return; } else if(formatType!=null && formatType.equals("9")) { obj.iDRMSGEDll_ConvertFile(inFile, outFile, "9" ); obj.iDRMSGEDll_Finalize(); // return; } else { message= "iDRMSGEDll_VerifyLicense failure"; } System.out.println("iDRMSGEDll_ConvertFile 1 success."); /*if (obj.iDRMSGEDll_ConvertFile("C:\Software\iDRS_15_1_7_2304\sample_pdfs\scan1_200dpi.pdf", "C:\Software\iDRS_15_1_7_2304\sample_pdfs\scan1_200dpi.out", 4) != 0 ) { obj.iDRMSGEDll_Finalize(); return; } System.out.println("iDRMSGEDll_ConvertFile 2 success."); if (obj.iDRMSGEDll_ConvertFile("C:\Software\iDRS_15_1_7_2304\sample_pdfs\scan1_300dpi.pdf", "C:\Software\iDRS_15_1_7_2304\sample_pdfs\scan1_300dpi.out", 4) != 0 ) { obj.iDRMSGEDll_Finalize(); return; } System.out.println("iDRMSGEDll_ConvertFile 3 success."); if (obj.iDRMSGEDll_ConvertFile("C:\Software\iDRS_15_1_7_2304\sample_pdfs\scan2_300dpi.pdf", "C:\Software\iDRS_15_1_7_2304\sample_pdfs\scan2_300dpi.out", 4) != 0 ) { obj.iDRMSGEDll_Finalize(); return; } System.out.println("iDRMSGEDll_ConvertFile 4 success.");*/ obj.iDRMSGEDll_Finalize(); System.out.println("iDRMSGEDll_Finalize success."); if(message.length()==0) { message = "success"; } } catch(Exception e) { e.printStackTrace(); message = e.getMessage(); } return message; } }