Tuesday, December 30, 2008

Don't Change Maven Artifact Names

Well lets get this started out with a rant shall we? Now I'm a bit of a Maven noob so it's possible I have it all wrong...

I've got a project that builds with mvn, all is well. Lets upgrade to Hibernate 3.3.1 and add the Jersey REST library - this is the kind of thing that Maven should make easy! Right? Not so much - I got this sorted out eventually but it was a pain. I used (and recommend) the Q4E maven plugin for eclipse http://code.google.com/p/q4e/ to get this sorted out.

OK here goes. In pom.xml, add the Jersey dependency and change the hibernate version to 3.3.1, no dice. The JAR file is not found. Look out on the JBoss maven repo and there's a directory with no JARs. A little research shows that they changed the artifact name from 'hibernate' to 'hibernate-core'. That should be it right?

Wrong - attempt to run unit tests and lots fail on an error about asm. I don't have a dependency on this. Here comes Q4E and the 'Analyze Dependencies' feature. It turns out that Jersey uses a new version of ASM (a bytecode lib) and Hibernate uses an old one. But wait, Hibernate 3.3.1 doesn't have a dependency on ASM. Hibernate 3.2.6 did however, and that's included as a dependency of Hibernate-Common-Annotations.

The problem here is that Maven will automatically prevent including two different versions of a library, but not if you go and change the &(*^ name. So the Hibernate guys changed from 'hibernate' to 'hibernate-entitymanager' (with separate 'hibernate-core' for reasons that I can understand) and now I inadvertently have two complete copies of Hibernate (and lots of extraneous jars) polluting my project.

Hard to figure out, simple to fix:


So all you library developers out there - don't change your artifactIds! Now with that said, this isn't really the Hibernate guys fault. Reorganization like this is healthy for a project like Hibernate. Unfortunately Maven doesn't handle it well, there's probably something they could do better to help with artifactId / groupId changes. How about a pointer to the previous version so that Maven can 'follow the version chain' over a name change?