Igor Kromin |   Consultant. Coder. Blogger. Tinkerer. Gamer.

I'm slowly coming around to liking Maven now. My first experience with it was less than nice, I put that down to not really understanding what it is and how to use it effectively. However one thing that has always bothered me with Maven was it's parent-child project version dependency. You have to specify the version in the parent pom.xml file, then for every child project (module) you have to reference that parent by its version. This is manageable if you only have a handful of child projects but once you get lots, changing your version number each release becomes a substantial task. I know there are plugins to manage this, but in my opinion this just complicates matters. Specifying the parent version as a property in one place would be so much easier.

Ultimately what I want from Maven is MNG-624 - automatic parent versioning feature to be implemented, however that's slanted to be reviewed in version 4.x some time and not applicable to my requirements now. I'm not the only one with such a requirement StackOverflow is filled with similar questions.

There is hope at the moment however. MNG-5576 and MNG-2199 have been implemented in Maven versions 3.2.1 and 3.2.2 respectively so when you combine these two features you get something that's quite flexible.

Goal: To be able to specify the version number for your entire build in a single place within your parent/super pom.xml file without updating any of the child pom.xml files or using additional plugins.
This no longer works as of Maven 3.5. If you're using this version of Maven (or later) please see this article: Multi module builds with Maven 3.5 and the parent-child pom version management.


This is what the parent/super pom.xml would look like...
 Super pom.xml
<?xml version="1.0" encoding="UTF-8" ?>
<project xmlns="http://maven.apache.org/POM/4.0.0">
<modelVersion>4.0.0</modelVersion>
<groupId>maven.test1</groupId>
<artifactId>maven-test1-parent</artifactId>
<version>${revision}</version>
<properties>
<revision>42.0</revision>
</properties>
<name>${project.artifactId}</name>
<description>Main POM file for ${project.artifactId}</description>
<packaging>pom</packaging>
<modules>
<module>Child1</module>
</modules>
</project>


The key lines above are line 7 and line 10. On line 7, I set the parent pom.xml version via the ${revision} property. This is possible to do since version 3.2.1. On line 10, I set this property to the actual value I want to use, in this case 42.0. You can verify this works by running mvn help:effective-pom.



Now the parent is dealt with, lets see the child pom.xml file.
 Child pom.xml
<?xml version="1.0" encoding="UTF-8" ?>
<project xmlns="http://maven.apache.org/POM/4.0.0">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>maven.test1</groupId>
<artifactId>maven-test1-parent</artifactId>
<version>[1.0,99.0)</version>
</parent>
<artifactId>maven-test1-child1</artifactId>
<name>${project.artifactId}</name>
</project>


The key line here is line 8. Here I specify the parent pom.xml version range as [1.0,99.0). This means it will match whatever the parent is between versions 1.0 and 99.0. This is possible to do since version 3.2.2. The actual version is not set on the child pom.xml since it will be inherited from the parent pom.xml, which in turn is defined via the ${revision} property.

This feels a little bit hacky and once you do hit your maximum specified version number you'll have to update all the child projects anyway, but I hope I would be retired by the time we hit version 99.0 on my current project!

Since this approach only works as of version 3.2.2, it is a good idea to use the Enforcer plugin to...well, enforce, the Maven version for your project.

That is done by adding the following to the parent pom.xml file.
 Parent pom.xml
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<version>1.4.1</version>
<executions>
<execution>
<id>enforce-versions</id>
<goals>
<goal>enforce</goal>
</goals>
<configuration>
<rules>
<requireMavenVersion>
<version>3.2.2</version>
</requireMavenVersion>
</rules>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>


The above is optional if you know that you'll always be using at least 3.2.2 as your Maven version.

-i

A quick disclaimer...

Although I put in a great effort into researching all the topics I cover, mistakes can happen. Use of any information from my blog posts should be at own risk and I do not hold any liability towards any information misuse or damages caused by following any of my posts.

All content and opinions expressed on this Blog are my own and do not represent the opinions of my employer (Oracle). Use of any information contained in this blog post/article is subject to this disclaimer.
Hi! You can search my blog here ⤵
NOTE: (2022) This Blog is no longer maintained and I will not be answering any emails or comments.

I am now focusing on Atari Gamer.