Resource loading gotcha – QUIZ!

December 4, 2006

To follow the meme of setting quizes in blog posts, here’s a real life Java gotcha that came up this morning. Pint to the first correct answer in a comment post (Justin and Joe need not apply, since I’ve told them already).

Justin is writing a Java project that checks CML files for experimental data errors. In this project he has a config file that stores the details of the checks to perform. He was loading it like this:

URL confUrl = getClass().getClassLoader()
File confFile = new File(confUrl.toUri());
Document doc = new Builder(confFile).build();

The config file was included as a resource in the jar, and everything worked fine in his test harness.

Then he used his jar in a separate project which is a web application. No dice. The Jar was there, the config file was in the jar, but the resource loading failed on the File constructor with a URISyntaxException saying “This URI is not hierarchical” or somesuch. For once I don’t think the message was particularly helpful, the solution just requires thinking about what’s happening.

Why didn’t the config file loading work in the web application? What did Justin do to solve this?

3 Responses to “Resource loading gotcha – QUIZ!”

  1. RichardJ Says:

    First, the error is not thrown by the File constructor, but by the confURL.toURI statement. The only place this could be differing between the test harness and the web application is in the particular ClassLoader that gets instantiated. Presumably the web application environment has a different implementation which is doing something funky to the path before passing it into findResource or somesuch. So probably you need to put in “jar:uk/ac/cam/wwmm/checkcml/config.xml” to force it to understand where you are referencing to, otherwise who knows where it might start looking for the resource.

    Is that close? Do I win a pint? 😉

  2. ojd20 Says:

    That’s decidedly close enough!

    The resource loader does return something like jar:uk/ac/foobar (this works, incidentally – the exception really is thrown in the File constructor).

    In the standalone application, there is a real live file. In the web application, config.xml has been bundled up into the jar, and is a series of bytes, rather than a full file record (probably compressed, also).

    What Justin did to solve this was to use a more robust way of loading resources; use .getResourceAsStream(), which works regardless of the source of the resource.

  3. ojd20 Says:

    Picture of Richard and his winning pint to follow…

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: