Earlier this fall, a problem showed up when the database guys first contributed Hibernate mappings. It was unclear how the Hibernate mappings could be causing the error we were getting — and it turned out that they weren’t; rather, they were exposing a different error that had previously been there, undetected.
I find these types of things really annoying before they’re figured out, and fascinating afterward. Here’s an email I sent out afterward:
From: Daniel Meyer
Sent: Wednesday, September 24, 2008 3:42 PM
Subject: RE: Build Failures: resolved
The “deployment fails the second time” issue has been resolved, and the CI servers are back in business.
For those who may be interested, the problem turned out to be a Maven config issue in [the functional test project]’s pom file.
(Note: you may need your techno-gibberish decoder goggles for the next details: )
In making ojdbc available to Liquibase for when we deliver schema changes, the ojdbc jar file got included in the war file. The config has been this way for several weeks, but we didn’t notice it until we just in the last few days got to the point of contributing Hibernate mappings, which starts the Persistence service, which needs ojdbc to actually work. At that time, the ojdbc jar in the war file fought with the ojdbc jar in JBoss’s server/default/lib directory, and just like when you were fighting with your sister over that cookie, nobody won and we got the NoClassDefFoundError.
(Or something vaguely similar to that.)
Thanks to [those who helped] for their help with this!
Now back to our regular programming…
It was bugging me that it took an extra day to find out that of all the possible dependency conflicts, the jta library was the one causing the deployment problem. It bugged me for two reasons: Not only is the jta library the “obvious” cause (hmm, we can’t instantiate a JtaSomethingSomething class… I wonder if it could be the jta library that’s causing a conflict?) — but also because the jta library was my first guess. I wanted to find out, why did I abandon that guess and try everything else?
Two Flaws in my Approach
There were two aspects of my approach that led to me not recognizing that the jta library was causing the issue:
- My practice was to search only the
server\default\deploy directory for duplicates, not realizing (well, at some level I realized it, but it didn’t dawn on me as important) that JBoss has many things that it deploys out of the
server\default\lib directory, and these can also cause conflicts.
- I was blindly searching for classes containing the string “jta”, I guess because when the connection to the JTA connection factory worked the message in the log mentioned a JtaTransactionManager. But in the end, the classes that were conflicting did not have the Jta in their names — they had javax.transaction. Suspecting the jta library, if I had opened up this library in the Referenced Libraries in Eclipse, I would have seen that the classes were all in the javax.transaction and javax.transaction.xa packages, and realized I should search for this string instead.
Sure enough, if I expand my JarSearch search to the whole
server\default tree (and don’t mark the jta library as provided in my .war project), I see this in JarSearch’s output:
Live and learn!
I decided to look around again to see if someone had already made a .[jrw]ar file searcher so we don’t have to do all that manual searching to find duplicately-deployed classes. A search of sourceforge.net turned up the JarSearch Eclipse plugin, made available under the GPLv2 license.
I extracted the .jar file from the download’s .zip file and copied it into my eclipse\plugins directory, then restarted Eclipse (JarSearch doesn’t seem to be set up to use the fancier method for installing an Eclipse plug-in using the Eclipse Update Manager). The most recent build of JarSearch is version 1.0 for Eclipse 3.2, but it seems to work ok on my Eclipse 3.3.2 installation.
Now when I hit Ctrl+H, I have a new Jar Search tab in the Search dialog, which allows me to search for a class inside archive files:
Notice that I added the rar extension to the list of filetypes to search inside of.
I click Search and JarSearch finds some classes with HAXA in their names inside .jar files that are nested inside two different .rar files. Wow, that’s nice!
Future Feature Wish: Saved Defaults
This plug-in is going to be so helpful to us. There’s just one thing I’d like to see improved — it would be nice if the options you pick could be saved as defaults for next time. As it is, after doing the search mentioned above, if I press Ctrl+H again and navigate to the Jar Search tab, the options are back to the original settings:
This means that I will always be needing to select the folder (which I think will usually be JBoss’s default\deploy folder) and add in the .rar extension. [Update 11/5/2008: Actually it turns out the folder I always want to search is the server\default folder, not server\default\deploy…]
That’s a minor gripe though. This utility is really going to be a help to us. Thanks, Alain!