Tag Archives: pom

Automatically Resolving Version Conflicts in Maven POMs When Merging

I’ve recently had a regular task of releasing projects from multiple branches, and then merging branches together. Handling this and any conflicts hasn’t been a big hassle when it is regularly updated, with one notable exception – Maven POM files. When they are merged the version changes on both branches always conflict.

There are ways I’ve got around it to date:

  • Subversion’s --accept mine-conflict and similar options can help resolve them quickly if you know ahead of time they are the only conflicts, without additional changes
  • If ending up with versions from the wrong branch, follow up with mvn versions:set -DnewVersion=... versions:commit
  • Sometimes the right merge tool or IDE will select the right one, or at least make it less repetitive to select the right one for each file

However, I was finding that in projects with a large number of POMs and occasional other conflicts, these were all a little too tedious. I’ve whipped up a basic script that can be used to eliminate the POM-based conflicts first, so that the remaining conflicts are only those you really need to deal with: Automatically resolve conflicts in Maven POMs after a merge — Gist. It doesn’t handle a lot of edge cases, but should work well enough for most uses.

This works pretty well with Git, and can be used with Subversion (if you automatically postpone all the resolve steps with --accept, or use a non-CLI tool to merge).

This is not something I’d want in a standard release/branch workflow – the problem could be avoided by different branching practices so that release commits are not merged. However if someone finds it useful, I’m sure they can improve on the Gist above, or perhaps patch the Maven SCM or Versions plugins to provide the capability more directly.

Experimental Maven support for condensed POMs using attributes

As I’ve just posted to the Maven developers list, I’ve always wanted to see an attribute based POM, so based on Nicolas’ suggestion I killed some time after waking up early this morning to do it.

Here’s what you’ll need to try it:

The issue is being tracked under MNG-3397.

The result is that something like this:

...
<dependencies>
  <dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>3.8.1</version>
    <scope>test</scope>
  </dependency>
  <dependency>
    <groupId>easymock</groupId>
    <artifactId>easymock</artifactId>
    <version>1.2_Java1.3</version>
    <scope>test</scope>
  </dependency>
  ...

Halves in length to something like this:

<dependencies>
  <dependency groupId="junit" artifactId="junit" version="3.8.1" scope="test"/>
  <dependency groupId="easymock" artifactId="easymock" version="1.2_Java1.3" scope="test"/>
  ...

What I did is basically convert all the primitive types in the model to attributes. I think more could be done – for instance, lists could be flattened if the parent element is not really needed for grouping, and I think plugin configuration should get the same treatment as above – but this gets a big win for minimal work. Also, the settings and profiles files could conceivably get the same treatment.

Most importantly – the work is completely backwards compatible. Maven detects v4.0.0 POMs and reads it like it used to. Even, as in the case of Archiva above, if there are different ones within a project.

Now, it’s early days for this change, and there are a few issues to note:

  • I switched from our bundled XPP3 based parser to StAX. This will likely introduce some quirks that will need to be ironed out through testing. I will likely in the future read the old models with the old parser, and the new ones with the new parser.
  • Some plugins may not work with this version (I’m guessing at this stage the release plugin falls into this category though I haven’t checked) – as I removed the old parser altogether. This should be easy to make compatible.
  • I haven’t tested performance with this new version – I expect that the v4.0.0 POMs will parse marginally slower than they used to and this may affect artifact resolution times. It also increased the size of the Maven download.

What comes next? Apart from correcting issues such as the above, I have in mind:

  • A simple plugin to convert from v4.0.0 to v4.1.0 for a POM file so you can try this out on your own projects.
  • Utilising the namespace for detecting the version so the modelVersion element is not required.
  • Further improvements to the format

What do Maven users think of this alternative format?

(And apologies to Don, I got carried away doing this instead of finishing the integration of his patches into the main branch – but I’ll resume that again shortly!)