Where did that class come from, anyway?. Tracing back through a few weblog referrer entries, I ended up at Clarkware Consulting, Inc, whose software page lists some useful utilities, including JWhich, a Java version of the "which" command under *nix operating systems.
For those of you who never used which , it was a command that when passed the name of an executable file, would traverse the PATH to discover out of which directory the command would be executed--it was invaluable for tracking down PATH problems. In Java, PATH problems equate to CLASSPATH problems. If you've been doing Java for any length of time, you've run into the classic "Doh! No wonder my code's failing--a much earlier version is before the latest build on the CLASSPATH!" Or worse, "Doh! Two different versions of the same jar on the CLASSPATH!" This utility will scan the CLASSPATH and report the absolute filename of the class passed on the command line. Cool.
All this really does, though, is help underscore how fundamentally broken the Java ClassLoader model really is. CLASSPATH is a gross hack and should be deprecated immediately (as in entirely absent from JDK 1.5 and up), and issues like verisoning and JAR-to-JAR dependencies resolved in a more sane and reasonable fashion. Anybody out there in bloggerland willing to go in with me on a new JSR? [The Mountain of Worthless Information]
Classpaths and ClassLoaders can be very frustrating. The real problem isn't the design of the ClassLoader per se, its we need some packaging mechanism on top of it that can correctly (and automatically) load all the corrent jars for us.
There's an interesting open source project called ClassWorlds which tries to provide a simple framework for doing this, using a simple text based config file to describe what jars a piece of software depends on so it can create the necessary tree of ClassLoaders to load (possibly conficting) things into the JVM. This is used right now inside Maven to load both Maven and the plugins and handle all kinds of class-loader issues you can get.
Incidentally, ClassWorlds uses a text file, not XML, since loading XML parsers and JAXP is a common cause of ClassLoader problems, particularly with versions of JAXP and XML parsers sometimes being available inside JDKs.
An interesting development of this is the uberjar mechanism, where a single, uber jar - containing all your code and all its dependencies, can be created. The neat thing is, you can create this automatically from your Maven build using the uberjar plugin, since Maven understands your projects dependencies.
The effect of the uberjar mechanism is not unlike static linking in the C world. It'd be fairly easy to extend this concept of uberjar to have shared library linking. In other words to reuse a Maven's repository of jars so that the uberjar can use jars found in a local repository; if a certain version of a jar is not present on a particular machine it can be dynamically downloaded from one of a number of remote repositories automatically.
Now that would totally rock.
2:49:55 PM
|