Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does maven enforcer ignore dependencyManagement section?

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.

like image 474
sevo Avatar asked Nov 17 '14 10:11

sevo


People also ask

What does Maven enforcer plugin do?

The Enforcer plugin provides goals to control certain environmental constraints such as Maven version, JDK version and OS family along with many more built-in rules and user created rules.

What is dependencyManagement in Maven?

Dependency management in Maven allows teams to manage dependencies for multi-module projects and applications. These can consist of hundreds or even thousands of modules. Using Maven can help teams define, create, and maintain reproducible builds.

How do you exclude a transitive dependency in Maven?

Exclude the transitive dependencyOpen the dependency POM and find the transitive dependency you want to exclude. Copy groupId and artifactId . In your project POM, underneath your active dependency, enter exclusions and using code completion paste the copied info of the dependency you want to exclude.

What is banned dependency?

This rule checks the dependencies and fails if any of the matching excludes are found. The following parameters are supported by this rule: searchTransitive - if transitive dependencies should be checked. Default is true.


1 Answers

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.

like image 173
Simon Wiesmann Avatar answered Oct 11 '22 16:10

Simon Wiesmann