I have a maven project consisting of a parent POM and several sub-modules. It compiles and runs fine within Intellij (I'm assuming this uses javac
and not Maven).
When I run maven clean install
, the build fails because of "RequireUpperBoundDeps", which from the documentation means a version resolved during the build is lower than a dependency's version for the same artifact. Here is the (sanitized) output:
[INFO] --- maven-enforcer-plugin:1.4:enforce (enforce-maven) @ my-service ---
[WARNING] Rule 1: org.apache.maven.plugins.enforcer.RequireUpperBoundDeps failed with message:
Failed while enforcing RequireUpperBoundDeps. The error(s) are [
Require upper bound dependencies error for com.h2database:h2:1.3.168 paths to dependency are:
+-com.example.services:my-service:1.0.0-SNAPSHOT
+-com.h2database:h2:1.3.168
and
+-com.example.services:my-service:1.0.0-SNAPSHOT
+-com.example.libs:my-libs:2.0.0
+-com.h2database:h2:1.3.168 (managed) <-- com.h2database:h2:1.4.190
]
This seems to be implying that h2
is a direct dependency of my-service
, but it is not declared as such in any poms, module or parent. h2
should only be coming from my-libs
. Furthermore, it claims that h2
is "managed" to be version 1.3.168
. I have no idea where it's getting this information. my-libs
uses h2
version 1.4.190
.
I've tried starting with a totally fresh .m2
directory, excluding h2
from the my-libs
dependency, explicitly including h2
under my-service
(both versions). Nothing works, and excluding h2
from the dependency results in a NoSuchPropertyException
on one of my classes that interact with the database (via JDBI).
How can I get maven to recognize the correct version of h2
to include and to successfully build my project?
Each maven dependency defined in the pom must have a version either directly or indirectly for example, through dependencyManagement or parent. That being said, if the version is not given, then the version provided in the dependencyManagement or the parent pom will be used.
of your question: If you don't specify a version there are various different outcomes: a) you will get an error... b) if you have defined the version in the dependency management of the project's parent's pom, then that version is taken. The parent of the project doesn't have to be an enclosing superproject.
Open 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.
Maven won't allow any other either. Build will fail if version is not found.
Someone wrote an excellent article HERE that provides and understanding of what is happening and possible solutions. Here is the summary -
For this deps tree in the error
+-com.example.services:my-service:1.0.0-SNAPSHOT
+-com.example.libs:my-libs:2.0.0
+-com.h2database:h2:1.3.168 (managed) <-- com.h2database:h2:1.4.190
The com.example.services:my-service
project has dependency on version 1.3.168
of com.h2database:h2
artifact. Also, com.example.libs:my-libs
needs the same artifact but of different version - 1.4.190
.
Declare com.h2database:h2:1.3.168
in your pom (Upgrade Scenario)
NB: This might not be a suitable solution for all projects.
Alternatively, you can exclude com.h2database:h2:1.4.190
from com.example.libs:my-libs
. That way, com.example.libs:my-libs
will end up using and older version in com.h2database:h2:1.3.168
(downgrade scenario)
To do the latter, your pom entry will look like this:
<dependency>
<groupId>com.example.libs</groupId>
<artifactId>my-libs</artifactId>
<version>2.0.0</version>
<exclusions>
<exclusion>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
</exclusion>
</exclusions>
</dependency>
It is a decision you have to make based on your project. I usually start by doing some investigations using mvn dependency:tree
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With