Does maven enforcer ignore dependencyManagement section?

2.7k views Asked by At

I have specified a version of a library in imported dependencyManagement section of a parent pom. I confirmed that my effective pom has only one occurence of this dependency. It is in dependencyManagement section:

<dependencyManagement>
    <dependency>
        <groupId>org.javassist</groupId>
        <artifactId>javassist</artifactId>
        <version>[3.18.1-GA]</version>
    </dependency>
</dependencyManagement>

That should override version for transitive dependencies depending on it. After installing (and reinstalling dependencies to match version bounds), org.apache.maven.plugins:maven-dependency-plugin:2.8:tree prints:

org.javassist:javassist:jar:3.18.1-GA:compile (version selected from constraint [3.18.1-GA,3.18.1-GA])

But (originally, without reinstalling dependencies) enforcer complains about wrong version:

[WARNING] Rule 1: org.apache.maven.plugins.enforcer.DependencyConvergence failed with message:
Failed while enforcing releasability the error(s) are [
Dependency convergence error for org.javassist:javassist:3.18.2-GA paths to dependency are:
...

And shows that first transitive dependency uses

org.javassist:javassist:3.18.2-GA

Which comes from dependency that in turn depends on:

<dependencies>
    <dependency>
        <groupId>org.javassist</groupId>
        <artifactId>javassist</artifactId>
        <version>3.18.2-GA</version>
    </dependency>
</dependencies>

and another uses

org.javassist:javassist:3.18.1-GA

Why is enforcer inconsistent with dependency tree? What could be wrong? If I use version bounds, will they be respected and I can skip using enforcer for this purpose?

Also, adding dependency to project module in question does not change anything.

1

There are 1 answers

0
Simon Wiesmann On

Tl;dr: dependencyManagement overrides the version of transitive dependencies

All the credit for this answer goes to Andy Dennie whose blog post I stumbled upon:
https://www.fizz-buzz.com/blog/2012/08/02/maven-enforcer-plugin-vs-dependencymanagement

dependencyManagement does two things - one of which is well known and the other is rarely mentioned.

  1. Set a default version for dependencies in submodules/child projects
  2. override the version of transitive dependencies

So the enforcer plugin does not ignore the dependencyManagement. But is unable to recognize the discrepancy since the transitive dependency's version was altered before it went to work. Andy Denny has a good suggestion on his blog on how to proceed:

  1. I don’t put dependencies in the dependencyManagement section of my top-level POM. I want to be alerted by maven-enforcer-plugin when I’ve got mismatches. Instead, I use version properties, as mentioned in my approach #1 above.
  2. When maven-enforcer-plugin notifies me of discrepancies, I try to see if I can get the artifacts involved to use the same version of the divergent dependency. If all the dependencies involved are in my own artifacts, I try to get them aligned on the same version of the dependency. If some artifacts are mine and some are from 3rd parties, I try to align my dependencies with the 3rd parties, and/or look for other versions of the 3rd party artifacts that have dependency versions that align with each other, and my code.
  3. If after doing the above, I still have unresolveable discrepancies, I choose what I think is the “best fit” version of the problematic artifact and specify that in the dependencyManagement section of the project POM where maven-enforcer-plugin reported the problem (not in my top-level POM). I add a comment to the dependency declaration in that POM noting the issue and the workaround, so that in the future, should I upgrade to a newer version of the dependency, I’ll see the note and can revisit whether the discrepancy can possibly then be resolved.

The trade-off here is that you have a working enforcer plugin that helps you with dependency hell, but have to do more by hand.