|
Helping ordinary people create extraordinary websites! |
Simplify Your Application Delivery with One-JARBy P. Simon Tuffs2005-04-22
Loading Resources Loading Resources During the development of One-JAR, findClass was the first thing I got working as a proof of concept. But when I started to deploy more complex applications I found I had to deal with loading resources as well as classes. This is where things got slippery. Casting about for a suitable method in ClassLoader to override in order to lookup resources, I picked the one with which I was most familiar, shown in Listing 3: Listing 3. The getResourceAsStream() method public InputStream getResourceAsStream(String name) {
Alarm bells should have been sounding at this point: I simply couldn't understand why URLs were being used to locate the resources. So I ignored this implementation and inserted my own, shown in Listing 4: Listing 4. One-JAR's implementation of getResourceAsStream() public InputStream getResourceAsStream(String resource) {
One last hurdle My new implementation of the getResourceAsStream() method seemed to do the trick, until I tried to One-JAR an application that loaded a resource using the URL url = object.getClass().getClassLoader().getResource() pattern; at which point things fell apart. Why? Because the URLs returned by the default implementation of ClassLoader are null, which broke the callers code. At this point things started to get really confusing. I had to figure out what URL should be used to refer to a resource inside a JAR file in the lib/ directory. Would it be something like jar:file:main.jar!lib/a.jar!com.a.A.resource? I tried all the possible combinations I could think of, none of which worked. The jar: syntax simply doesn't support nested JAR files, which left me facing an apparent dead-end to the whole One-JAR approach. While most applications don't seem to use ClassLoader.getResource some definitely do, and I wasn't happy with an exclusion that said "If your application uses ClassLoader.getResource() you can't use One-JAR." And finally, a solution ...! While I was trying to figure out the jar: syntax, I stumbled onto the mechanism by which the Java Runtime Environment maps URL prefixes to handlers. This was the clue I needed to fix the findResource problem: I would simply invent my own protocol prefix called onejar:. I could then map the new prefix to a protocol handler, which would return the byte stream for the resource, as shown in Listing 5. Note that Listing 5 represents code in two files, the JarClassLoader and a new file called com/simontuffs/onejar/Handler.java. Listing 5. findResource and the onejar: protocol com/simontuffs/onejar/JarClassLoader.java Tutorial Pages: » Power Programming with Custom Classloaders » Overview of One-JAR » Problems and solutions » Enter the JarClassLoader » Loading Resources » Bootstrapping the JarClassLoader » In Conclusion » Resources First published by IBM DeveloperWorks |
|