Just in the last few days, our deployments of a certain module started failing with a NoClassDefFound error on a class from the ojdbc5 jar. Suspecting that the ojdbc5 jar might be duplicated somewhere, I found (using my beloved JarSearch) that indeed, sometimes the module was being built with the ojdbc5 jar in it.
Background and Analysis
The ojdbc5 artifact was listed in the project’s pom file as a compile-scope <dependency> under a certain profile. That profile was activated by our CI server when deploying schema changes, because Liquibase needed it around. That was why the .war was sometimes built with ojdbc5 in it and sometimes not.
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 then 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.
So we needed ojdbc5 to be around at build time (at least when a certain Maven profile is active), but not be included in the war file.
Our first fix was to declare the ojdbc5 artifact as an extension for the build instead of as a dependency of the profile. That worked (that is, it allowed the build to succeed and didn’t put the ojdbc5 jar in the resulting war file), but it made the ojdbc5 artifact available to all builds of our war file, meaning we could accidentally start depending on ojdbc to be there. While not a stopper, it wasn’t ideal.
It turns out that by declaring ojdbc5 as a test-scope dependency in the profile where it was originally was (the one that is only active when we’re deploying schema changes), we get all three things we wanted
- ojdbc5 is around at build time if and only if that one Maven profile is active
- ojdbc5 is never included in the war file