Java.library.path中的java.lang.UnsatisfiedLinkError no ***** .dll

时间:2009-09-10 07:19:01

标签: java dll java-native-interface web-applications

如何在我的网络应用程序中加载自定义dll文件?我尝试了以下方法,但失败了。

  • system32文件夹中复制了所有必需的dll,并尝试在Servlet构造函数System.loadLibrary中加载其中一个
  • tomcat_home/shared/libtomcat_home/common/lib
  • 中复制了所需的dll
  • 所有这些dll都在web-application
  • WEB-INF/lib

15 个答案:

答案 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

然后它无法在PATHjava.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);

请在Changing Java Library Path at Runtime点击抢劫。

答案 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

的人

我面临同样的例外;我尝试了一切和重要的事情来使其发挥作用:

  1. 正确版本的pdf lib.jar(在我的情况下,它是在服务器运行时中保存的错误版本jar)
  2. 创建一个文件夹并保留pdflib jar并在PATH变量中添加该文件夹
  3. 它与tomcat 6一起使用。

答案 7 :(得分:2)

可怜我!花了一整天的时间在这里。如果任何一个团体重复这个问题,请在这里写下来。

我试图像Adam建议的那样加载,但后来遇到了AMD64与IA 32异常。如果在任何情况下按照Adam(无疑是最好的选择)演练后,尝试拥有64位版本的最新jre 。确保你的JRE和JDK是64位,你已经正确地将它添加到你的类路径中。

我的工作示例如下:unstatisfied link error

答案 8 :(得分:1)

  1. 如果您相信已将本地lib的路径添加到%PATH%,请通过以下方法再测试一次:

    System.out.println(System.getProperty(“ java.library.path”))

它应该实际显示您的dll是否位于%PATH%

  1. 重新启动IDE Idea,是的,在我将env变量添加到%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;





    }


}