I encountered a lovely piece of Classpath Hell thanks to Weblogic (7.0) today. Or rather a colleague of mine did; I just helped him figure it out.
He was refactoring his Ant build script so that he didn’t need a copy of @weblogic.jar@ sitting in his project tree, but would use a copy installed elsewhere. The only problem was that when he update the classpath for his unit tests, they stopped working. No output, not even on debug; it just stopped the test execution cold. After looking into this for a while, he came and got me.
Well, we tried the obvious things first. Was the property for the jar file misspelt? Was the _value_ of the property wrong (did it point to the wrong path)? Maybe the installed weblogic.jar was corrupted in some way? All of these turned up negative.
I was getting annoyed that the tests weren’t produce any errors. We could tell from the test log file that the test suite was being created correctly, and that the test run was started, but it didn’t put out any output. After a few minutes of digging around, we put in an exception handler into the test suite to catch any errors ourselves. Sure enough, we got one: NoSuchMethodError
for the junit.framework.TestCase.name()
method.
This deserved a big “WTF is going on here?”. However, we’d already worked out the answer in general. The reason why the tests weren’t working has to do with Weblogic’s “everything but the kitchen sink” approach to packaging their jar files. I’ve come across this before; weblogic.jar has copies of a million other things in it, and if you don’t want to use their version, you need to be careful with your classpath. However, I didn’t realise that, in addition to replicating (for example) Oracle JDBC drivers, they’d used a Class-Path entry in the Manifest file for the jar. In this was a reference to… Ant 1.4. And, in particular, the optional library with it that specified a old and broken JUnit test runner (broken with more recent versions of JUnit, that is). This old version was also the reason there wasn’t any output. We’d discovered the manifest file earlier one, and suspected it to be the cause of the problem, but we were thinking bad XML or JDBC classes (both of which were also referred to in the manifest file). With the trace, however, it became very clear what was going on.
Due to how his classpath was set up, the reference to weblogic.jar was being picked up before the Ant classes that he wanted to use. When he used the local weblogic.jar, this wasn’t a problem; the refernces in the manifest file didn’t point to anything valid, so they didn’t do anything. With the installed weblogic.jar, however, they were perfectly valid, and caused his build to break. Nasty stuff that really puzzled us for a while.
Moral(s) of the story: Libraries shouldn’t try to be all things to all people. Weblogic, in particular, is desperately crying out for a separate (lightweight) client jar file that can be used for compling and accessing servers, while keeping the heavier jar for the runtime. Oh, and make sure “kitchen-sink” libraries got at the end of the classpath, where they can do the least damage.