带有重新分发的JRE的Java:无法找到本机依赖项

时间:2014-11-07 12:29:04

标签: java java-native-interface

我想用我的应用程序重新分发jre。我在使用本机库时遇到问题。

假设我有一个jar:application.jar,它依赖于两个本机库(dll):a.dll和b.dll。所有这些都在同一个目录中。

Application.jar包含一个类:Test.java     包com.mytest;

public class Test {
    static {
        System.loadLibrary("a");
        System.loadLibrary("b");
    }

    public static void main(String[] args) {
        System.out.println("hooray");
    }
}

执行时:java -jar application.jar它运作正常。

然后我将我的JRE文件夹从程序文件复制到文件夹:C:\data\jre\

现在我执行:c:\data\jre\bin\java.exe -jar application.jar它失败并显示以下消息:

Exception in thread "main" java.lang.UnsatisfiedLinkError: C:\data\application\b.dll: The specified procedure could not be found
at java.lang.ClassLoader$NativeLibrary.load(Native Method)
    at java.lang.ClassLoader.loadLibrary1(ClassLoader.java:1965)
    at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1890)
    at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1880)
    at java.lang.Runtime.loadLibrary0(Runtime.java:849)
    at java.lang.System.loadLibrary(System.java:1088)
    at com.mytest.Test.<clinit>(Test.java:6)

当我删除加载库b的行时,它可以正常工作。鉴于库ab位于同一目录中,为什么系统无法找到b

1 个答案:

答案 0 :(得分:1)

解决方案是b.dll依赖于其他库。其中一个库也放在jre bin目录中,但不在C:\windows\system32\中。

使用正常的java命令运行时,它会首先查看system32文件夹,在该文件夹中找不到dll。然后,它会查找放置a.dllb.dll的文件夹。

使用c:\data\jre\bin\java.exe命令运行时,它会先查找c:\data\jre\bin\the.dll中的dll,然后再查看放置a.dllb.dll的文件夹。

如果没有此dll,则不允许重新分发JRE。因此,解决方法是在加载System.load("C:/full/path/to/dll/the.dll")之前使用b.dll明确加载正确的dll。

这是一次艰难的搜索,但关键是使用procmon并比较两次执行。