我使用仅包含ClassPath
元素的JAR来构建我的Java应用程序的类路径,并且我遇到了一个奇怪的行为:我可以从中提到的JAR中加载类。 ClassPath
元素,但缺少部分(或全部)资源。
示例:我的full-classpath.jar
只包含META-INF/MANIFEST.MF
一般内容和此行:
ClassPath: foo-service.jar bar-service.jar service-main.jar
service-main.jar
包含com.pany.project.Main
。
当我运行java -cp full-classpath.jar com.pany.project.Main
时,就可以了。
但foo-service.jar
和bar-service.jar
包含META-INF/services/....
当我从Maven单元测试中调用java.util.ServiceLoader
时,它可以看到foo
和bar
服务。当我java -cp full-classpath.jar com.pany.project.Main -service foo
时,我在日志中看到一个空的服务列表。
更糟糕的是,当我致电Main.class.getClassLoader().getResources("META-INF/MANIFEST.MF")
时,我只会获得full-classpath.jar
的清单。其他三个JAR中的清单文件丢失了,因为我可以从这些JAR中加载类,所以没有意义。当我手动构建整个类路径时,它也有效。它只在我使用ClassPath
中的full-classpath.jar
元素时失败。
任何想法可能出错或如何调试?
我正在使用Java 8.
答案 0 :(得分:0)
清单属性Class-Path
在sun.misc.URLClassPath.JarLoader.parseClassPath(URL, String)
中处理。此方法从sun.misc.URLClassPath.JarLoader.getClassPath()
调用一次。在getClassPath()
开头,您可以找到以下代码:
if (index != null) {
return null;
}
if (metaIndex != null) {
return null;
}
表示:如果您的类路径JAR包含索引或"元索引" (不管是什么),Class-Path
属性被忽略。
我无法说明为什么Java仍然可以从Class-Path
属性中提到的JAR加载类,但删除索引可以解决资源加载问题。