为什么我可以从JAR加载类而不是资源?
我使用只包含一个ClassPath
元素打造的类路径为我的Java应用程序一个罐子,我遇到一个奇怪的行为:我可以从ClassPath
元素中提到的JAR文件加载类,但部分(或全部)资源缺失。为什么我可以从JAR加载类而不是资源?
例子:我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/....
服务定义当我调用java.util.ServiceLoader
从Maven的单元测试,它可以同时看到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加载类!它也适用于我手动构建整个类路径。它只在full-classpath.jar
中使用ClassPath
元素时失败。
任何想法可能是错误的或我怎么能调试吗?
我使用Java 8
清单属性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;
}
这意味着:如果你的classpath JAR包含索引或“元指数”(不管它是什么),该Class-Path
属性将被忽略。
我不知道为什么的Java仍然可以加载类从Class-Path
属性中提到的JAR文件,但删除索引修复资源加载问题。