tytk
tytk

Reputation: 2332

Maven pulling in dependency that is not specified in POM

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?

Upvotes: 7

Views: 14366

Answers (3)

papigee
papigee

Reputation: 7368

Someone wrote an excellent article HERE that provides an 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.

Upvotes: 11

Ali Karaca
Ali Karaca

Reputation: 3821

General answer: Just declare missing dependencies in your pom.xml

Upvotes: 1

tytk
tytk

Reputation: 2332

I figured out that the h2 dependency was being pulled in from the parent pom (the parent of my-service). mvn dependency:tree was deceiving as it shows h2 as a direct dependency to my-service, which in my mind meant that it should be declared in the my-service pom. It was not delcared in the my-service pom - however, it was declared in the parent pom. That is where the conflicting version came from.

Declaring h2 in the my-service pom with a specified version fixed the upper bound dependencies error.

Upvotes: 6

Related Questions