java.library.path中的java.lang.UnsatifiedLink错误号******.dll

java.library.path中的java.lang.UnsatifiedLink错误号******.dll,java,dll,java-native-interface,web-applications,Java,Dll,Java Native Interface,Web Applications,如何在web应用程序中加载自定义dll文件?我尝试了以下方法: 复制了system32文件夹中所有必需的DLL,并尝试在ServletconstructorSystem.loadLibrary 将所需DLL复制到tomcat_home/shared/lib和tomcat_home/common/lib 所有这些DLL都位于WEB应用程序的WEB-INF/lib中,为了使System.loadLibrary()正常工作,库(在Windows上是DLL)必须位于路径上的某个目录中,或者位于jav

如何在web应用程序中加载自定义dll文件?我尝试了以下方法:

  • 复制了
    system32
    文件夹中所有必需的DLL,并尝试在
    Servlet
    constructor
    System.loadLibrary
  • 将所需DLL复制到
    tomcat_home/shared/lib
    tomcat_home/common/lib

所有这些DLL都位于WEB应用程序的
WEB-INF/lib

中,为了使
System.loadLibrary()
正常工作,库(在Windows上是DLL)必须位于
路径
上的某个目录中,或者位于
java.library.PATH
系统属性中列出的路径中(因此可以像Java一样启动Java-Djava.library.path=/path/to/dir

此外,对于
loadLibrary()
,您可以指定库的基本名称,但末尾没有
.dll
。因此,对于
/path/to/something.dll
,您只需使用
System.loadLibrary(“something”)

您还需要查看得到的确切的
未满足链接错误
。如果它是这样说的:

Exception in thread "main" java.lang.UnsatisfiedLinkError: no foo in java.library.path
Exception in thread "main" java.lang.UnsatisfiedLinkError: com.example.program.ClassName.foo()V
然后它在
路径
java.library.PATH
中找不到foo库(foo.dll)

Exception in thread "main" java.lang.UnsatisfiedLinkError: no foo in java.library.path
Exception in thread "main" java.lang.UnsatisfiedLinkError: com.example.program.ClassName.foo()V
然后,库本身就出了问题,因为Java无法将应用程序中的本机Java函数映射到其实际的本机对应函数

首先,我将在您的
System.loadLibrary()
调用中放置一些日志,以查看该调用是否正确执行。如果它引发异常或不在实际执行的代码路径中,那么您将始终得到上面解释的后一种类型的
unsatifiedlinkerror

作为旁注,大多数人使用本机方法将其
loadLibrary()
调用放入类中的静态初始值设定项块中,以确保始终只执行一次:

class Foo {

    static {
        System.loadLibrary('foo');
    }

    public Foo() {
    }

}

对于那些正在寻找
java.lang.UnsatifiedLinkError:no pdf\u java in java.library.path

我也面临着同样的例外;我尝试了一切,重要的是:

  • pdf lib.jar的正确版本(在我的例子中,保存在服务器运行时的jar版本是错误的)
  • 创建一个文件夹并将pdflib jar保存在其中,然后将该文件夹添加到PATH变量中

  • 它和tomcat 6一起工作。

    可怜的我!花了一整天的时间在这上面。如果有人复制了这个问题,就把它写在这里

    我试图按照Adam的建议加载,但随后发现AMD64 vs IA 32异常。如果在任何情况下按照Adam(无疑是最佳选择)的演练进行操作,请尝试使用最新jre的64位版本。确保您的jre和JDK是64位的,并且您已将其正确添加到类路径中


    我的工作示例如下:

    您可以使用
    System.load()
    提供您想要的绝对路径,而不是相应操作系统的标准库文件夹中的文件

    如果您想要已有的本机应用程序,请使用。如果您想要提供自己的应用程序,则使用load()可能会更好


    您还应该能够在正确设置
    java.library.path
    的情况下使用
    loadLibrary
    。请参阅显示检查的两个路径的实现源代码(OpenJDK)

    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的类加载器仍然引用此DLL。但是,您的Web应用程序现在正在使用新的类加载器运行,并且由于同一个JVM正在运行,并且一个JVM不允许对同一DLL进行两次引用,因此您无法重新加载它。因此,您的Web应用程序无法访问现有的DLL,也无法加载新的DLL。因此。。…你被卡住了

    概述了重新加载的webapp为何在新的独立类加载器中运行,以及如何克服此限制(在非常高的级别上)

    解决方案是稍微扩展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) {
            }
    
        }
    
    然后将一个只包含这个编译类的jar放入TOMCAT_HOME/lib文件夹

    现在,在您的webapp中,您只需强制Tomcat引用此类即可,操作如下:

      Class.forName("awesome.Foo");
    
    现在,您的DLL应该加载到公共类加载器中,即使在重新部署之后,也可以从您的webapp引用

    有道理吗


    可以在google代码中找到工作参考副本。

    如果您需要加载一个与您所在目录(如当前目录)相关的文件,这里有一个简单的解决方案:

    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());
    

    如果问题是System.loadLibrary找不到有问题的DLL,一个常见的误解(Java的错误消息加强了这一点)答案是系统属性java.library.path。如果将系统属性java.library.path设置为DLL所在的目录,则system.loadLibrary确实会找到您的DLL。但是,如果您的DLL反过来又依赖于其他DLL(通常是这样),则java.library.path将帮不上忙,因为加载依赖于ndent DLL完全由操作系统管理,操作系统对java.library.path一无所知。因此,在启动JVM之前,最好绕过java.library.path,简单地将DLL目录添加到LD_library_path(Linux)、DYLD_library_path(MacOS)或path(Windows)中


    (注意:我使用的术语是DLL或共享库的一般意义上的“DLL”)

    在运行时更改“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);
    

    请在以下位置查看:。

    对于windows,我发现当我将filles(jd2xsx.dll调用&ftd2x.dll)加载到windowws/system32文件夹时,解决了问题。然后,我的新fd2xx.dll出现了问题,必须