我有一些遗留代码从现有jar中读取配置文件,例如:
URL url = SomeClass.class.getResource("/configuration.properties");
// some more code here using url variable
InputStream in = url.openStream();
显然它之前有效,但是当我执行此代码时,URL有效,但我在第三行收到IOException,说它无法找到该文件。网址类似于“file:jar:c:/path/to/jar/somejar.jar!configuration.properties
”,所以它看起来不像是类路径问题 - java非常清楚可以找到文件的位置..
上述代码是ant任务的一部分,在执行任务时失败。
奇怪 - 我将代码和jar文件复制到一个单独的类中,它按预期工作,属性文件是可读的。
在某些时候,我将ant任务的代码更改为
URL url = SomeClass.class.getResource("/configuration.properties");
// some more code here using url variable
InputStream in = SomeClass.class.getResourceAsStream("/configuration.properties");
现在它可以工作 - 直到它在另一个实现了类似访问模式的类中崩溃。
为什么它之前有效,为什么它现在失败了?我目前看到的唯一区别是,旧版本是用java 1.4完成的,而我现在正在尝试使用Java 6.
解决方法
今天我在构建服务器上安装了Java 1.4.2_19,并让ant使用它。令我非常沮丧的惊喜:问题消失了。在我看来,java 1.4.2可以处理这种类型的URL,而Java 1.6则不能(至少在我的上下文/环境中)。
我仍然希望得到一个解释,虽然我正在面对重写部分代码以使用Class#getRessourceAsStream的工作,它表现得更稳定......
答案 0 :(得分:2)
ClassLoader.getResourceAsStream
的典型实现是:
public InputStream getResourceAsStream(String name) {
URL url = getResource(name);
try {
return url != null ? url.openStream() : null;
} catch (IOException e) {
return null;
}
}
Class.getResource
和getResourceAsStream
的行为相同。
所以看起来你要么使用ClassLoader
的一个奇怪而破碎的子类,要么你的测试中有一些错误。
答案 1 :(得分:1)
它适用于getresourceasstream,因为它位于类路径中,但它不适用于URL,可能是因为URL不正确。
我不知道getResource创建的URL是否正常,或者协议没有正确的处理程序(不是file:jar:c:/myjar.jar!configuration.properties
或类似的东西(有两个冒号) ?)
答案 2 :(得分:1)
答案 3 :(得分:0)
使用包含空格的文件URL时,有几个Java版本存在错误。 “/ path / to / jar”可能不是你的真正路径,所以我至少假设这是你遇到的。你的代码至少在理论上是可以的。