theINtoy
theINtoy

Reputation: 3708

How to update version number in Maven POMs

We have a very modular Maven pom set up, with common jars and specific jars all being bundled in to a war and ear. As there is so much reuse amongst the 70+ modules we do not use multi-module and each module can and does have its own lifecycle and can be released independently of any other module.

All modules inherit from various parent poms and ultimately every pom inherits from a master POM where all the external versions such as spring and the common local module versions are defined.

This works ok until we come to do a release. If the master POM requires a change, which it does occasionally, ALL poms need to be updated one way or another. I am aware that the maven versions plugin can update a specific POM with the latest SNAPSHOT versions etc, but this only works at the individual POM level.

We would like to be able to alter all poms once a release has been completed, iteratively.

We do not use multi-module POMs and are not able to change our build process to use this mechanism.

I have read around SO and the nearest to the problem is here. https://stackoverflow.com/a/3615417/1279002

Writing a shell script seems to be one solution, but we have a Windows and Linux mix of development and build systems. I am sure other will have solved this issue. Can anybody advise how they have solved this?

Upvotes: 1

Views: 3135

Answers (1)

Alex
Alex

Reputation: 2485

In a similar setup, I have all my parent POMs always stay at 1.0.0-SNAPSHOT and setup various properties in the parent POMs to track internal module version numbers (so this setup now centralizes both dependency management versions AND custom module versions [via properties] into the parent POMs).

So if I need to update the reference to some com.myco:module-x, I can do this:

  1. Edit the appropriate parent POM and set the <module-x.version>1.2.3</module-x.version> property to the new value
  2. Rebuild/install the parent POM
  3. Rebuild the target end-application (ear, war, jar app etc).

Where in module-x's POM it's definition may be something like this:

<groupId>com.myco</groupId> 
<artifactId>module-x</artifactId>
<version>${module-x.version}</version>

And any POMs which reference com.myco:module-x refernece it via ${module-x.version} as well.

At this point, the build of the application will pickup the changes in the parent POM and thus any references it has to any properties defined in the parent POM.

There's some subtle nuances in doing this in terms of when/how the "middle man" modules need to get rebuilt...

But I really don't believe there is any silver bullet here.

The approach we've taken works pretty well, coupled with Jenkins to automate rebuilds of modules with interdependencies whenever parent POMs change.

The benefit here is that you seldom need to modify anything but the parent POMs, ever. The middle-man modules and application POMs don't need to be updated to get new version numbers, etc.

The biggest caveat though is that two rebuilds of a given module at the same version could result in a different artifact, for example:

  1. module-x has a dependency on module-y:1.2.3
  2. module-x is built (jar is created with a MANIFEST referencing module-y:1.2.3)
  3. parent POM is modified to set <module-y.version>1.2.4</module-y.version>
  4. module-y is rebuilt to create the 1.2.4 artifact
  5. module-x is built (jar is created with a MANIFEST referencing module-y:1.2.4)

But note that #2 and #5 both built module-x with the same version for module-x, but with two different embedded MANIFEST's referencing different module-y versions.

We overcome this nuance by automating all the dependent modules with our Jenkins CI server

Upvotes: 1

Related Questions