【发布时间】:2012-08-11 00:38:41
【问题描述】:
我正在开发一个使用工作 JVM 来做各种事情的应用服务器。
工作 jvm 使用 -cp 开关启动并指定包含供应商库和其他重要功能的 JAR 文件。
我有一个非常有趣的问题,其中 jar 文件 CLASSES 正确加载和执行代码,但是任何时候他们尝试访问 jar 文件中的资源(特别是使用 getResourceAsStream() 方法),然后它就声称找不到它。我已经验证这些资源肯定存在于正在加载的 JAR 中,事实上,如果我操纵 JAR 以在外部定位资源,它就可以工作。问题是这些都是专有库,不附带源代码,所以我不得不通过反编译和方法入口断点来做所有事情。
也许最奇怪的部分是这些库已经好几个月没有改变了,并且一直在其他(包括生产)应用服务器中工作。
它们在 JRE 1.6.0_17 上
所以我的问题是
- 为什么带有 -cp 条目的 JVM 能够从 jar 中加载 CLASSES 而不能从 RESOURCES 中加载
- 此领域中的任何内容是否从 JRE 1.6.0_06 更改为 1.6.0_17(最近已更改)
澄清一下,在 JAR 结构中,这些资源位于 jar 的根目录中,即:
resource.prop
META-INF/Manifest
package/package/class.class
JAR 本身在加载时显然位于类路径中。 但是,以下所有内容都解析为 NULL(是的,这让我发疯了,所以我确实尝试了所有 3 个):
Jarclass.getClassLoader().getResourceAsStream("./resource.prop");
Jarclass.getClassLoader().getResourceAsStream("/resource.prop");
Jarclass.getClassLoader().getResourceAsStream("resource.prop");
这看起来类似于Can't access resource in a JAR on all computers,但没有解决该问题。
【问题讨论】:
-
唯一想到的是:JAR 可能使用自定义类加载器,这些加载器依赖于 JRE 实现中的一些奇怪行为(编写类加载器并非易事)。问题通常仅限于来自一个供应商的库吗?如果做Jarclass.getClassLoader().toString(),是否说明这不是JRE创建的ClassLoader?
-
非常有见地的评论预测了我在原始帖子中甚至没有提到的事情。您绝对正确,其中一个供应商正在使用自定义类加载器,并且它覆盖了 JRE 标准类加载器,特别是用于加载资源。我的库都没有改变,但我没想到检查其他包含更改的类加载器的库。我调查了一下,发现这就是问题所在——供应商在他们对自定义类加载器所做的更改中犯了一个错误。谢谢!
标签: java class resources jar jvm