ATTENTION: Workarounds available

An alternate solution that is working with maven 2.2.+ can be found here:

http://jira.codehaus.org/browse/MNG-624?focusedCommentId=210447&page=com.atlassian.jira.plugin.system.issuetabpanels%3Acomment-tabpanel#action_210447

However we still suffer with MNG-2971.

Update: This is no solution because of MNG-4060.

Easier maintenance of <version> in large projects

Motivation

If you develop a large project with maven, you will typically split your code into various modules organized in a large tree (POM hierarchy). Maven is a great tool to support the development of such project. However there is a major drawback addressed in this toppic:

Every node in your POM hierarchy has a pom.xml with a groupId, artifactId and a version. Besides you have references to other POMs (or artifacts - however you see it) in your pom:

Now the problem is about those references that point to POMs of your own project. For <groupId> that is typically the same throughout the solution is simply to use <groupId>${project.groupId}</groupId> but your groupId will normaly never change anyhow. But on the other hand the <version> typically points to the current local version of the referenced pom. Now the version will change often and this becomes a maintenance problem if you have to spread the versions of your artifacts all over the referencing POMs. I know that this gap of maven is somehow covered by maven-release-plugin but discussions have shown that this is NOT always a suiteable workaround.

So following the maven concept "convention over configuration" maven should offer a way to express a project-internal reference that points to the current version of that module defined in pom.xml without explicitly knowing this version. The suggestion is to be able to omit the version in such case. This would allow to have the version as a single point of information in the according pom while references still have the chance to explicitly specify a (older) version.

Please note that versions can already be omitted if the dependency is versioned via the dependencyManagement-section (e.g. of the parent POM). However this does NOT really help here because it also requires a lot of redundancies and maintenance overhead.

Two views on a POM

At this point we have to distinguish that there are two different points of view when maven is looking at a POM:

An important issue for a new maven feature is that it is compatible with other maven versions and therefore will NOT break existing builds in any way. Therefore the suggested feature is planned to be only visible for the development view. To archieve this goal, maven has to be changed in a way such that it automatically adds omitted <version> tags in POMs that are installed in or deployed to a repository. To avoid mistakes or missusage of such feature maven could also reject processing POMs with missing <version> tag, that are not read as pom.xml but retrieved from a repository (including local repo).

The solution in detail

When you call maven from your toplevel project (where the root pom.xml is), it will scan the entire project tree of your project adding all nodes to the reactor. Having this complete reactor, maven is able to determine the version of each module in the reactor from the according pom.xml that has been parsed. So in that case if an individual module is build (actual goal[s] are invoked) maven can logically complete all the omitted <version> tags for modules available in the reactor (This actually means that parsing, processing and validating pom.xml can no more be done in one single step). Now if maven has logically completed the POM, it can do its build as if the missing tags have been there from the start (for install/deploy see below).

But what if maven is invoked on a sub-tree of the project? Here we have to distinguish two things:

Another important thing is that ArtifactInstaller and ArtifactDeployer need to guarantee, that the pom.xml is no more copied as is (1:1) but rather a new file is written where the missing tags are added. So in the end some other maven user can NOT see if this feature was used or not and can still use a maven version that does NOT support this feature without problems. For ultimate flexibilty the process should be such that maven keeps the original pom.xml untouched but creates a new one in ${project.build.directory}/pom-transformed.xml (concept already introduced in maven 2.1+) where the omitted <version> tags are filled in. Now additional plugins could potentially do post-processing on that POM (but thats not the point of this toppic). Finally the ArtifactInstaller and ArtifactDeployer will use this new POM rather than the original one.

Examples

To clarify the hole idea it might help to look at some examples:

We assume the following project structure (names are folders and <artifactId>):

If you click on the modules, you will see the pom.xml and the equivalent without the new feature.

Example 1: You invoke "mvn install" on "child-a-1".

maven will do the following (many other steps ignored):

Example 2: You invoke "mvn install" on "child-a-2".

maven will do the following (many other steps ignored):

Issues

 The feature discussed here is inspired by some existing JIRA-issues: