我有一个小型 Java 程序“Test.java”,它依赖于在同一目录中的单独 jar 文件中找到的类“TestLib”。
“项目”结构:
$ ls
Test.java Test.class testlib.jar
Test.java 和 testlib.jar 是 stub 工件,它们重现了我在更大的应用程序中看到的类路径问题。Test.java 所做的只是从 testlib.jar 实例化一个类,然后退出:
import com.TestLib;
public class Test {
public static void main(String[] args) {
System.out.println("Before instantiating testlib");
new TestLib();
System.out.println("After instantiating testlib");
}
}
我的测试 jar 有问题的测试库类:
$ unzip -l testlib.jar
...
com/TestLib.class
...
(jar 包含许多其他类和 meta-inf 文件,此处省略)
我可以编译这个小项目:javac Test.java -classpath .:testlib.jar
我尝试使用 command 运行它java -classpath .:testlib.jar Test
,并获得输出:
Before instantiating testlib
Exception in thread "main" java.lang.NoClassDefFoundError: com/TestLib at Test.main(Test.java:6)
它找不到“TestLib”!
有趣的是,当我将-verbose
标志添加到我的 java 调用时,我可以看到它甚至从未打开我的库 jar 以在那里查找 TestLib:
$ java -verbose -classpath .:testlib.jar Test 2>&1 | grep "Opened"
[Opened /Library/Java/JavaVirtualMachines/jdk1.8.0_172.jdk/Contents/Home/jre/lib/rt.jar]
[Opened /Library/Java/JavaVirtualMachines/jdk1.8.0_172.jdk/Contents/Home/jre/lib/jsse.jar]
[Opened /Library/Java/JavaVirtualMachines/jdk1.8.0_172.jdk/Contents/Home/jre/lib/jce.jar]
是什么决定了 JVM 是否打开一个 jar 文件来查找丢失的类?是否有任何 META-INF 或其他 jar 内容阻止 jar 被 JVM 打开?我应该采取哪些步骤来解决为什么在运行时找不到“TestLib”?