我想用我的应用程序重新分发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
的行时,它可以正常工作。鉴于库a
和b
位于同一目录中,为什么系统无法找到b
?
答案 0 :(得分:1)
解决方案是b.dll
依赖于其他库。其中一个库也放在jre bin目录中,但不在C:\windows\system32\
中。
使用正常的java
命令运行时,它会首先查看system32文件夹,在该文件夹中找不到dll。然后,它会查找放置a.dll
和b.dll
的文件夹。
使用c:\data\jre\bin\java.exe
命令运行时,它会先查找c:\data\jre\bin\the.dll
中的dll,然后再查看放置a.dll
和b.dll
的文件夹。
如果没有此dll,则不允许重新分发JRE。因此,解决方法是在加载System.load("C:/full/path/to/dll/the.dll")
之前使用b.dll
明确加载正确的dll。
这是一次艰难的搜索,但关键是使用procmon并比较两次执行。