Newsletter sign-up
View all newsletters

Enterprise Java Newsletter
Stay up to date on the latest tutorials and Java community news posted on JavaWorld

Sponsored Links

Optimize with a SATA RAID Storage Solution
Range of capacities as low as $1250 per TB. Ideal if you currently rely on servers/disks/JBODs

URLs: Smart resource identifiers

Keep resource names and resource loading strategies separate

  • Print
  • Feedback

Page 5 of 5

    "urljoin:"<url_1>","<url_2>","...


will first read data from url_1, then url_2, and so on. I demo it by reading jwlogo.gif in two chunks. A less crazy example of using urljoin: is to merge application-global and module-specific .properties configurations into one while keeping the underlying files separate.

The new scheme's implementation is quite straightforward (it is in the class URLJoinHandler in this article's download). Next, I create a new url.properties resource with a mapping

    urljoin = URLJoinHandler,


split jwlogo.gif into two pieces, and package everything together with the new classes into plugin.jar. The new URL scheme is now picked up automatically:

   java -cp urldemo.jar;plugin.jar URLDemo      urljoin:clsloader:images/jwlogo_1.gif,clsloader:images/jwlogo_2.gif 


I want to emphasize what just happened: I extended the original application by merely adding a new jar to the classpath without changing a single line of code or even editing an existing property file. This is simply the ultimate in pluggability. I used this approach to extend my original URLFactory's capabilities, but the same idea obviously works in any plug-in scenario. And it does not require scanning anything on disk.

A sure sign of a novice Java programmer is to instead use code that figures out a classpath string of some kind and actually proceeds to scan all classpath directories and archives looking for "all classes in a given package" or other signs of plug-ins. That is really a hack that adds a lot of disk position-dependent code in your application. Java may one day learn to load classes from other types of archives besides .zip files (in fact, some JVMs already do that), so do not make your application dependent on a particular disk archive format. Let getResources() and a pattern of identically named classloader resources guide you towards disk position-independent nirvana.

So, what about JAR URLs or java.net.URIs?

Suffice it to say that JAR URLs are useful, but not for abstracting away the resource location details. Java 2 Platform, Standard Edition (J2SE) 1.4 also adds java.net.URI. This new class possibly fits the need for a generic resource identifier better than java.net.URL, but it is too new to be of considerable value at the time of writing. A URI needs to be converted to a URL via toURL(), and the tricks used for coercing URI data to java.net.URL format under the hood are similar to what I used in my URLStreamHandlers above.

Concluding remarks

Finally, I would like for you to take away at least the following points:

About the author

Vladimir Roubtsov has programmed in a variety of languages for more than 13 years, including Java since 1995. Currently, he develops enterprise software as a senior engineer for Trilogy in Austin, Texas.
  • Smart resource descriptors like java.net.URLs help abstract away not only the location of resources but also many aspects of the resource loading strategy. If the requirements force you to revert to using files, using URLs can help insulate this fact from the rest of your code. It is not hard to reinvent custom descriptor classes, but java.net.URLs have the advantage because they are already integrated into core Java.
  • With a little foresight, you can make your applications extendible and pluggable without code or configuration changes by using ClassLoader.getResources() and a pattern of identically named resources.


  • Print
  • Feedback

Resources