java.lang.UnsatisfiedLinkError no *****。dll在java.library.path中
我怎样才能加载我的web应用程序中的自定义dll文件? 我尝试了以下方法,但是失败了。
- 复制
system32
文件夹中的所有必需的DLL,并尝试在Servlet
构造函数System.loadLibrary
加载其中的一个 - 复制
tomcat_home/shared/lib
和tomcat_home/common/lib
所需的dll - 所有这些DLL都在
WEB-INF/lib
应用程序的WEB-INF/lib
中
为了使System.loadLibrary()
工作,库(在Windows上,一个DLL)必须位于PATH
上的某个目录中, 或者位于java.library.path
系统属性中列出的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
那么它在PATH
或java.library.path
找不到foo库(foo.dll)。 如果它像这样说:
Exception in thread "main" java.lang.UnsatisfiedLinkError: com.example.program.ClassName.foo()V
那么库本身就有问题,因为Java不能将应用程序中的本地Java函数映射到其实际本机对象。
首先,我会把你的System.loadLibrary()
调用一些日志logging,看看是否正确执行。 如果它抛出一个exception或者不在实际执行的代码path中,那么你总是会得到上面解释的后一种UnsatisfiedLinkError
。
作为一个旁注,大多数人将他们的loadLibrary()
调用放到类中的静态初始化块中,以确保它始终只执行一次:
class Foo { static { System.loadLibrary('foo'); } public Foo() { } }
Adam Batkin原来的答案会引导你到一个解决scheme,但是如果你重新部署你的webapp(不重新启动你的web容器),你应该遇到下面的错误:
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的ClassLoader仍然引用此DLL。 但是,您的web应用程序现在正在运行一个新的ClassLoader,并且由于相同的JVM正在运行,并且JVM不会允许2个引用到同一个DLL,所以无法重新加载它。 因此,你的web应用程序不能访问现有的DLL,不能加载一个新的。 所以….你被卡住了。
Tomcat的ClassLoader文档概述了为什么重新加载的Web应用程序运行在一个新的独立ClassLoader中,以及如何解决这个限制(在很高的级别)。
解决办法是稍微扩展Adam Batkin的解决scheme:
package awesome; public class Foo { static { System.loadLibrary('foo'); } // required to work with JDK 6 and JDK 7 public static void main(String[] args) { } }
然后把包含JUST这个编译类的jar放到TOMCAT_HOME / lib文件夹中。
现在,在你的webapp中,你只需强迫Tomcat引用这个类,这可以简单地完成:
Class.forName("awesome.Foo");
现在你的DLL应该被加载到普通的类加载器中,甚至可以在重新部署之后从你的web应用中引用。
合理?
可以在google代码static-dll-bootstrapper上find工作参考副本。
在运行时更改“java.library.path”variables是不够的,因为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库path 。
您可以使用System.load()
提供您想要的绝对path,而不是相应操作系统的标准库文件夹中的文件。
如果您想要本地应用程序已经存在,使用System.loadLibrary(String filename)
。 如果你想提供你自己的,你可能更好的加载()。
你也应该能够使用loadLibrary
和java.library.path
正确设置。 查看ClassLoader.java
的实现源,显示两个path被检查(OpenJDK)
在问题是System.loadLibrary找不到问题的情况下,一个常见的误解(由Java错误信息加强)是系统属性java.library.path是答案。 如果将系统属性java.library.path设置为您的DLL所在的目录,那么System.loadLibrary确实会find您的DLL。 但是,如果你的DLL反过来依赖于其他的DLL,那么java.library.path就无法帮助,因为依赖的DLL的加载完全由操作系统来pipe理,而操作系统对java.library一无所知。path。 因此,在启动JVM之前,绕过java.library.path并简单地将DLL的目录添加到LD_LIBRARY_PATH(Linux),DYLD_LIBRARY_PATH(MacOS)或Path(Windows)总是更好。
(注:我在DLL或共享库的通用意义上使用术语“DLL”。)
对于那些正在查找java.lang.UnsatisfiedLinkError: no pdf_java in java.library.path
我面临同样的例外; 我尝试了一切和重要的事情,使其工作是:
- 正确版本的pdf lib.jar(在我的情况下,它是错误的版本jar保存在服务器运行时)
- 制作一个文件夹并将pdflib jar放入其中,然后在PATHvariables中添加该文件夹
它与tomcat 6一起工作。
可怜的我 ! 花了整整一天的时间。如果任何机构复制这个问题,在这里写下来。
我试图按照亚当的build议加载,但后来被AMD64和IA 32exception所困扰。如果在按照亚当(无疑是最好的select)的演练之后工作,尝试使用最新版本的64位版本。确保你的JRE和JDK是64位的,你已经正确地将它添加到你的类path中。
我的工作示例在这里: 不满意的链接错误
如果你需要加载一个与你已经存在的目录相关的文件(比如在当前目录下),这里有一个简单的解决scheme:
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的path可能不起作用。
我使用的是Mac OS X Yosemite和Netbeans 8.02,我得到了同样的错误,我发现的简单解决scheme就像上面这样,当你需要将本地库包含在项目中时,这是非常有用的。 那么下一个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
我希望这对某个人有用。 我find解决scheme的链接在这里: java.library.path – 它是什么以及如何使用
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\IRIS SA\iDRS_15_2_for_Win64_15_2_11_1717\lib\idrskr .lib C:\Program Files\IRIS SA\iDRS_15_2_for_Win64_15_2_11_1717\bin\iDRMSG idgeDll.dll C:\Program Files\IRIS 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 Server\100\Tools\Binn\ C:\Program Files\Microsoft SQL Server\100\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\IRIS SA\iDRS_15_2_for_Win64_15_2_11_1717\lib\idrskrn15.lib;C:\Program Files\IRIS SA\iDRS_15_2_for_Win64_15_2_11_1717\bin\iDRMSGEBridgeDll.dll;C:\Program Files\IRIS 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 Server\100\Tools\Binn\;C:\Program Files\Microsoft SQL Server\100\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)\\IRIS 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; } }