如何在我的网络应用程序中加载自定义dll文件?我尝试了以下方法,但失败了。
system32
文件夹中复制了所有必需的dll,并尝试在Servlet
构造函数System.loadLibrary
中加载其中一个tomcat_home/shared/lib
和tomcat_home/common/lib
WEB-INF/lib
中
答案 0 :(得分:142)
为了使System.loadLibrary()
正常工作,库(在Windows上,DLL)必须位于PATH
或上某个目录中的路径中java.library.path
系统属性(因此您可以像java -Djava.library.path=/path/to/dir
一样启动Java。)
此外,对于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函数映射到实际的本机Java函数。
首先,我会在System.loadLibrary()
调用周围进行一些日志记录,看看是否正常执行。如果它抛出异常或不在实际执行的代码路径中,那么您将始终获得上面解释的后一种UnsatisfiedLinkError
。
作为旁注,大多数人使用本机方法将loadLibrary()
调用放入类中的静态初始化块,以确保它始终只执行一次:
class Foo {
static {
System.loadLibrary('foo');
}
public Foo() {
}
}
答案 1 :(得分:12)
在运行时更改'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);
答案 2 :(得分:10)
Adam Batkin的原始答案将引导您找到解决方案,但如果您重新部署Web应用程序(无需重新启动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。但是,您的webapp现在使用新的ClassLoader运行,并且由于同一个JVM正在运行且JVM不允许2个引用同一个DLL,因此您无法重新加载它。因此,您的webapp无法访问现有的DLL,也无法加载新的DLL。所以......你被困住了。
Tomcat's ClassLoader documentation概述了为什么重新加载的webapp在一个新的隔离的ClassLoader中运行,以及如何解决这个限制(在很高的层次上)。
解决方案是稍微扩展Adam Batkin的解决方案:
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应该加载到公共类加载器中,即使在重新部署之后也可以从您的webapp引用。
有意义吗?
可以在Google代码static-dll-bootstrapper上找到工作参考副本。
答案 3 :(得分:7)
您可以使用System.load()
提供所需的绝对路径,而不是相应操作系统的标准库文件夹中的文件。
如果您想要已存在的本机应用程序,请使用System.loadLibrary(String filename)
。如果你想提供自己的,你可能会更好地使用load()。
您还应该能够loadLibrary
正确使用java.library.path
。有关正在检查两个路径的实现源(OpenJDK)
ClassLoader.java
答案 4 :(得分:6)
如果问题是System.loadLibrary无法找到有问题的DLL,一个常见的误解(由Java的错误消息加强)是系统属性java.library.path就是答案。如果将系统属性java.library.path设置为DLL所在的目录,则System.loadLibrary确实会找到您的DLL。但是,如果您的DLL依赖于其他DLL(通常就是这种情况),那么java.library.path也无济于事,因为依赖DLL的加载完全由操作系统管理,操作系统对java.library一无所知。路径。因此,在启动JVM之前,绕过java.library.path并简单地将DLL的目录添加到LD_LIBRARY_PATH(Linux),DYLD_LIBRARY_PATH(MacOS)或Path(Windows)几乎总是更好。
(注意:我在DLL或共享库的一般意义上使用术语“DLL”。)
答案 5 :(得分:3)
如果你需要加载一个相对于你已经存在的目录的文件(比如在当前目录中),这是一个简单的解决方案:
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());
答案 6 :(得分:2)
对于那些正在寻找java.lang.UnsatisfiedLinkError: no pdf_java in java.library.path
我面临同样的例外;我尝试了一切和重要的事情来使其发挥作用:
它与tomcat 6一起使用。
答案 7 :(得分:2)
可怜我!花了一整天的时间在这里。如果任何一个团体重复这个问题,请在这里写下来。
我试图像Adam建议的那样加载,但后来遇到了AMD64与IA 32异常。如果在任何情况下按照Adam(无疑是最好的选择)演练后,尝试拥有64位版本的最新jre 。确保你的JRE和JDK是64位,你已经正确地将它添加到你的类路径中。
我的工作示例如下:unstatisfied link error
答案 8 :(得分:1)
如果您相信已将本地lib的路径添加到%PATH%,请通过以下方法再测试一次:
System.out.println(System.getProperty(“ java.library.path”))
它应该实际显示您的dll是否位于%PATH%
答案 9 :(得分:0)
对于Windows我发现当我将filles(jd2xsx.dll调用& ftd2xx.dll)加载到windowws / system32文件夹时,这解决了问题。然后我有一个问题,我的新fd2xx.dll与参数有关,这就是为什么我不得不加载这个DLL的旧版本。我将不得不在以后表达这一点。
注意:jd2xsx.dll调用ftd2xx.dll所以只是设置jd2xx.dll的路径可能不起作用。
答案 10 :(得分:0)
我正在使用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 – What is it and how to use
答案 11 :(得分:0)
我遇到了同样的问题,错误是由于dll的重命名。
库名称也可能写在dll内的某个地方。
放回原来的名称后,我可以使用System.loadLibrary
答案 12 :(得分:0)
很简单,只需在Windows的命令行中编写java -XshowSettings:properties,然后将所有文件粘贴到java.library.path显示的路径中即可。
答案 13 :(得分:0)
首先,您要确保本机库的目录位于java.library.path
上。了解如何进行here。然后,您可以调用System.loadLibrary(nativeLibraryNameWithoutExtension)
-确保在文件库名称中不包括文件扩展名。
答案 14 :(得分:-2)
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 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\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 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)\\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;
}
}