tags:

views:

478

answers:

3

I have some legacy code that reads a configuration file from an existing jar, like:

URL url = SomeClass.class.getResource("/configuration.properties");
// some more code here using url variable
InputStream in = url.openStream();

Obviously it worked before but when I execute this code, the URL is valid but I get an IOException on the third line, saying it can't find the file. The url is something like "file:jar:c:/path/to/jar/somejar.jar!configuration.properties" so it doesn't look like a classpath issue - java knows pretty well where the file can be found..

The above code is part of an ant task and it fails while the task is executed.

Strange enough - I copied the code and the jar file into a separate class and it works as expected, the properties file is readable.

At some point I changed the code of the ant task to

URL url = SomeClass.class.getResource("/configuration.properties");
// some more code here using url variable
InputStream in = SomeClass.class.getResourceAsStream("/configuration.properties");

and now it works - just until it crashes in another class where a similiar access pattern is implemented..

Why could it have worked before, why does it fail now? The only difference I see at the moment is, that the old build was done with java 1.4 while I'm trying it with Java 6 now.

Workaround

Today I installed Java 1.4.2_19 on the build server and made ant to use it. To my totally frustrating surprise: The problem is gone. It looks to me, that java 1.4.2 can handle URLs of this type while Java 1.6 can't (at least in my context/environment).

I'm still hoping for an explanation although I'm facing the work to rewrite parts of the code to use Class#getRessourceAsStream which behaved much more stable...

+1  A: 

It works with getresourceasstream because it is in the classpath, but it doesn't work with the URL maybe because the URL is not ok.

I don't know if the URL that getResource is creating is not ok, or there isn't a correct handler for the protocol (wouldn't it be file:jar:c:/myjar.jar!configuration.properties or something by the like (with two colons?)

helios
My Java6 runtime prints `jar:file:/C:/Archivos%20de%20programa/Java/jdk1.6.0_14/jre/lib/rt.jar!/java/util/ArrayList.class` when I ask for Class.getResource("/java/util/ArrayList.class"). It's the correct format I think.
helios
thx for the correct URL format - I wasn't able to look it up correctly when writing this question ;) But that's not the problem. It must have worked before and the snippet works with the same library in a 'standalone context' (iaw some dummy class with a main method)
Andreas_D
I'm thinking about a permissions problem. It's really a weird problem :)
helios
A: 

There are bugs in several Java versions when using file URLs containing spaces. "/path/to/jar" is probably not your real path, so I at least assume that this is what you're running into. Your code is at least in theory ok.

jarnbjo
Thanks, but not an issue here - the path doesn't contain spaces.
Andreas_D
Why don't you post the exact URL and the exact exception which is thrown (not just "something like"). Perhaps then, someone is able to help you?
jarnbjo
The code is disclosed so I do not paste anything to the internet. Although it would be easier, because now I have to invent examples to explain my problems. Spaces was a guess, not a bad guess, but believe me, if the path had had spaces, I would have had investigated in that area or mentioned that fact in the question.
Andreas_D
+2  A: 

A typical implementation of ClassLoader.getResourceAsStream is:

public InputStream getResourceAsStream(String name) {
    URL url = getResource(name);
    try {
        return url != null ? url.openStream() : null;
    } catch (IOException e) {
        return null;
    }
}

Class.getResource and getResourceAsStream behave the same as each other.

So it looks like either you are using a strange and broken subclass of ClassLoader, or there is some mistake in the tests on your side.

Tom Hawtin - tackline
Good hint - now that I have two jdks installed I'll have a look at the implementations in both versions. Maybe that leads to an answer.
Andreas_D