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

NOTE: This article is 3 years or older so its information may no longer be relevant. Read on at your own discretion! Comments for this article have automatically been locked, refer to the FAQ for more details.
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

Skip down to comments...
Hope you found this post useful...

...so please read on! I love writing articles that provide beneficial information, tips and examples to my readers. All information on my blog is provided free of charge and I encourage you to share it as you wish. There is a small favour I ask in return however - engage in comments below, provide feedback, and if you see mistakes let me know.

If you want to show additional support and help me pay for web hosting and domain name registration, donations, no matter how small, are always welcome!

Use of any information contained in this blog post/article is subject to this disclaimer.
 
comments powered by Disqus
Other posts you may like...