Aggregation versus inheritance in maven?
In Josh Bloch’s Effective Java we are urged to “Favor aggregation over inheritance”. It didn’t take too long to convince me that this was a good idea. I was sold so quickly because of the countless projects where good meaning java programmers have over-engineered deeply nested class hierarchies all in the name of proper OO design. No where can this be more damaging then when structuring your organization’s corpus of maven artifacts.
To give an example, imagine a centrally managed POM file with all the “approved” versions of artifacts — I don’t have to imagine this, since that is exactly what I did. In this “parent” pom was a “dependencyManagement” section with all the preferred versions of libraries within the organization. Sounds like a good idea right? Wrong! Now imagine that you have 100+ projects all inheriting from this parent project… Because all the version numbers for 3rd party jars are centrally managed, any revving of any specific jar (say log4j goes from 1.2.13 to 1.2.15) will cause a re-release of anything inheriting from it. Yup… that’s 100+ redeployments — hows that for a nasty impact analysis.
The alternative has been to not inherit from any pom for fear that it may change. For the most part, this is what I’ve been doing. Unfortunately this approach has problems too — namely dependency convergence. That is the convergence of differing versions of the artifacts declared throughout your enterprise. Maven has a whole algorithm for calculating which dependency gets included and which ones do not. Typically, the dependency declared “closest” to where you are wins. This can lead to some very frustrating side effects, where most of them sound like this, “Why in the world is THIS version of this jar included.” This has led many a frustrated engineer (including myself) to “pin” the version in the current POM, even if that project doesn’t have a dependency on that asset directly (yuck).
Well, could much of the crying and nashing of teeth be ending? Did the maven guys come up with something in between? A way to aggregate dependencies without using the parent pom? It appears that as of version 2.0.9, their is a new scope on a dependency called import. Here is a sample from a pom which uses this scope:
<dependencyManagement> <dependencies> <dependency> <groupId>maven</groupId> <artifactId>A</artifactId> <version>1.0</version> <type>pom</type> <scope>import</scope> </dependency> <dependencies> <dependencyManagement>
What this says is to import the dependencies declared in the artifact A into the current project! Time will tell whether or not this added feature will be all that it seems to be, but in the meantime, I raise my glass to the maven engineers and other contributors who continue to push these tools forward. Bravo!
1 Comment »
Leave a Reply
| Next »
-
Recent
-
Links
-
Archives
- May 2008 (2)
-
Categories
-
RSS
Entries RSS
Comments RSS
Great Idea Paul! Our team architect is just doing this as well!