tags:

views:

4160

answers:

7

If you use Maven2 as a build system for a project containing many artefacts, you have the version number of the resulting build scattered in all pom.xml. In many of them even twice - in the version tag of the artefact itself and in the version tag of the parent. Thus, you have to change and check in new versions of all pom.xml on every version switch. This is a little annoying, especially if you have to code for several bug fixing and a development version in parallel. Is there a way around that?

CLARIFICATION: My question is about the many versions of every single pom.xml that you get over time in your source control system that differ only by the version number of the pom and / or the version number of the parent pom. Ideally, you should only need to change the pom whenever you add a dependency or something.

For example you have a project with the artifacts foo-pom (the parent pom to all), foobar-jar, foobaz-jar and foo-war. In the first release the version is 1.0 - which appears in every pom.xml. In the second release the version is 1.1 - which again appears in every pom.xml. So you have to change every pom.xml - this is annoying if you release as often as you should.

UPDATE: If you think this is important: not having to specify the parent version is already being considered. Please go to the maven JIRA issue and vote for it to get it more noticed and more likely to be added as an enhancement in an upcoming release. You need to create/have a JIRA login for that.

There is another Stackoverflow Question that is basically about the same problem.

+4  A: 

Hello,

On my project, I have such a problem. To reduce the number of versions I define in my parent pom.xml some properties, which correspond to the versions of each module:

<properties>
    <project-version>1.0.0</project-version>
    <!-- Same version than the parent for the module 'commons' -->
    <project-commons-version>${project-version}</project-commons-version>
    <!-- A specific version for the 'business' module -->
    <project-business-version>1.0.1</project-business-version>
    ...

And then, in the pom.xml of each module, I use these properties. The problem is that I must clearly input the version of the parent in this pom.xml. For example, in my business pom.xml, I have:

<project>
  <modelVersion>4.0.0</modelVersion>
  <!-- I must indicate the version of the parent -->
  <parent>
    <groupId>my.project</groupId>
    <artifactId>parent</artifactId>
    <version>1.0.0</version>
  </parent>
  ...
  <dependencies>
    <!-- However, in my dependencies, I use directly the properties defined in the parent's pom.xml -->
    <dependency>
      <groupId>my.project</groupId>
      <artifactId>project-persistence</artifactId>
      <version>${project-persistence-version}</version>
    </dependency>

However, I really suggest that you have a look to the release plugin that will take care of modifying all the version numbers for you.

romaintaz
That is the pattern we are using as well - except for the release plugin. I was wondering whether you can somehow avoid putting the parent version in every pom.xml. But it seems you have to live with the many versions of the pom in the source control that differ only by the parent version.
hstoerr
I think this approach can be complemented with Maven version plug-in: http://mojo.codehaus.org/versions-maven-pluginIt can increment the parent.version tag in child projects automatically; see versions:update-child-modules goal.
Dan
+4  A: 

Does this article provide a solution for your problem ?

The idea is to declare the version number for the whole project as a property, namely "aversion" (pun intended), in the parent pom. The parent pom's own version number can be anything as long as it ends with "SNAPSHOT".

Child modules' version is specified via the ${aversion} property. Children's reference to their parent's version is hard coded. However, since the parent pom's version is a SNAPSHOT, child modules will see the changes in the parent pom. In particular, if the parent pom changes the value of ${aversion}, the children will see the change.

Not a perfect solution according to the comments.

And the release plugin doesn't solve the real problem: merging.
Having endless copies of the version number all over the place means lots of conflicts when bringing branches back together.

Note:

with Maven 2.0.9 (latest one - April 2008) I have simply been omitting the version element from the individual modules as they will inherit the version from their parent. This works with the groupId as well if your modules share the same groupId as their parent.

VonC
VonC is right in that you can omit YOUR pom's groupId and artifactId if you want them to be the same as the parent. But the challenge still exists that you have to specifically declare the version of your parent, even in a multimodule hierarchical build.
Matthew McCullough
+1  A: 

This is an idea for a possible extension of maven that would solve the problem. Currently you have to write the a version of the artifact and of the parent pom in the pom.xml. There already is a way to give an absolute location for the parent pom:

<parent>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>my-parent</artifactId>
    <version>2.0</version>
    <relativePath>../my-parent</relativePath>
</parent>

If you allow omitting of both the version of the parent and of this pom iff maven is able to access the parent pom by the relative path, you are done. The version is only mentioned in the parent pom and nowhere else.

hstoerr
Compare http://jira.codehaus.org/browse/MNG-1012
hstoerr
+5  A: 

I've run into similar problems while working on a large system built with Maven 2.

In my opinion, the downside of the typical multi-module structure is that all modules have to share the same version. This is indeed annoying: even if your next release only consists in a bugfix in foobar-jar, you need to change the global version everywhere (be it manually or with maven-release-plugin) and roll a new release of every component. In my case, I built various WAR/EAR applications, so my customer would ask me why I delivered a new version of both app1 and app2, when only app1 was supposed to be impacted.

The opposite approach is to manage each component as an independent project, with its own independent version. This is more flexible as it allows partial releases, but you now need to track all these versions manually (know which versions your next delivery will consist in, make sure internal dependencies are consistent, etc.). This can quickly become a nightmare in a large application.

I've long thought about a way to combine both approaches: the flexibility of independent versions, without giving up the global coherency of the system. I tried the same approach as romaintaz, and ran into the same problem. Finally, I came up with this idea: http://out-println.blogspot.com/2008/10/maven-modules-with-independent-versions.html.

Consider it as 'experimental', as I didn't get to try it live in the end (for non-technical reasons). But I think it would do the trick.

Olivier
+4  A: 

There's another StackOverflow thread that also covers this topic that you might want to look at.

In short, not having to specify the parent version when using inheritance is already being considered. Please go over to JIRA and give it a vote bump to get it more noticed and more likely to be added as an enhancement in an upcoming release.

Matthew McCullough
A: 

Here is another lightweight workaround until the maven issue is resolved. In one large project we do no longer put the pom.xml itself in the version control, but a pom-template.xml which just contains a placeholder for the version number. After updating the project tree from version control you need to run a little ant script that generates the actual pom.xml in every directory. This is annoying, but less annoying than to have to put up with all those bothersome pom versions.

hstoerr
A: 

We have exactly this problem. We have a a large number (around 10) of different projects some of which depend on each other. The folder containing the projects has a parent pom for the entire set of projects. Each time we created a new branch we had to go into each and every pom file to change the <version> element and also the <version> for the parent, and all this editing was annoying.

After reading this question and the answers here I realized that the situation was hopeless. Each project could inherit the <version> element from the parent pom so that one was easy to eliminate, but we obviously could not inherit the <version> for the <parent>.

Unfortunately, I forgot to tell my colleague it was impossible, so he fixed it. His solution was to add a property to the parent pom file:

<properties><currentVersion>2.6.1-SNAPSHOT</currentVersion></properties>

Then in the child pom files we declared the parent version tag like this:

<version>${currentVersion}</version>

I don't know why this works. I don't see how it can find the right parent pom without specifying the version number. But for me (maven version 1.5.0_22) it is working.

mcherm