2

我正在使用一个只包含一个ClassPath元素的 JAR 来为我的 Java 应用程序构建类路径,我遇到了一个奇怪的行为:我可以从ClassPath元素中提到的 JAR 加载类,但缺少一些(或全部)资源。

示例: Myfull-classpath.jar仅包含META-INF/MANIFEST.MF具有通常内容的 a 和这一行:

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.jarbar-service.jar包含服务定义META-INF/services/....

java.util.ServiceLoader当我从 Maven 单元测试调用时,它可以同时看到 thefoobarservice。当 I 时java -cp full-classpath.jar com.pany.project.Main -service foo,我在日志中看到一个空的服务列表。

更糟糕的是,当我打电话时Main.class.getClassLoader().getResources("META-INF/MANIFEST.MF"),我只从full-classpath.jar. 其他三个 JAR 的清单文件丢失了,这没有意义,因为我可以从这些 JAR 加载类!当我手动构建整个类路径时它也可以工作。只有当我ClassPathfull-classpath.jar.

任何想法可能是错误的或我如何调试它?

我正在使用 Java 8。

4

1 回答 1

0

manifest 属性Class-Pathsun.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 加载类,但删除索引修复了资源加载问题。

于 2017-06-20T08:22:08.257 回答