18

After updating Firefox I changed versions of libraries to higher ones. Following errors appeard: [ERROR] Dependency convergence error for commons-collections:commons-collections:3.2.2 paths to dependency are:

[ERROR] +-net:serenity.pom.gradle:0.0.1-SNAPSHOT
[ERROR] +-net.serenity-bdd:serenity-core:1.1.29-rc.3
[ERROR] +-org.seleniumhq.selenium:htmlunit-driver:2.20
[ERROR] +-commons-collections:commons-collections:3.2.2
[ERROR] and
[ERROR] +-net:serenity.pom.gradle:0.0.1-SNAPSHOT
[ERROR] +-net.serenity-bdd:serenity-core:1.1.29-rc.3
[ERROR] +-io.appium:java-client:3.3.0
[ERROR] +-commons-validator:commons-validator:1.4.1
[ERROR] +-commons-collections:commons-collections:3.2.1
[ERROR] and
[ERROR] +-net:serenity.pom.gradle:0.0.1-SNAPSHOT
[ERROR] +-net.serenity-bdd:serenity-core:1.1.29-rc.3
[ERROR] +-commons-collections:commons-collections:3.2.2
[ERROR] ]
[ERROR] -> [Help 1]

Dependency tree looks like:

[INFO] +- net.serenity-bdd:serenity-core:jar:1.1.29-rc.3:test
[INFO] |  +- org.seleniumhq.selenium:htmlunit-driver:jar:2.20:test
[INFO] |  +- commons-collections:commons-collections:jar:3.2.2:test
[INFO] |  +- io.appium:java-client:jar:3.3.0:test
[INFO] |  |  \- commons-validator:commons-validator:jar:1.4.1:test
[INFO] |  |     +- commons-beanutils:commons-beanutils:jar:1.8.3:test
[INFO] |  |     \- commons-digester:commons-digester:jar:1.8.1:test

How to solve this problem? Can I manually switch the library?

PS Here is my pom.xml

<dependencies>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>net.serenity-bdd</groupId>
        <artifactId>serenity-core</artifactId>
        <version>1.1.29-rc.3</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-simple</artifactId>
        <version>1.7.7</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>net.serenity-bdd</groupId>
        <artifactId>serenity-jbehave</artifactId>
        <version>1.9.0</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.assertj</groupId>
        <artifactId>assertj-core</artifactId>
        <version>3.2.0</version>
        <scope>test</scope>
    </dependency>
</dependencies>

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-enforcer-plugin</artifactId>
            <version>1.4</version>
            <executions>
                <execution>
                    <id>verify</id>
                    <phase>validate</phase>
                    <goals>
                        <goal>enforce</goal>
                    </goals>
                    <inherited>true</inherited>
                </execution>
            </executions>
            <configuration>
                <failFast>true</failFast>
                <rules>
                    <DependencyConvergence></DependencyConvergence>
                    <requireReleaseDeps>
                        <onlyWhenRelease>true</onlyWhenRelease>
                    </requireReleaseDeps>
                    <requireJavaVersion>
                        <version>${java.version}</version>
                    </requireJavaVersion>
                </rules>
            </configuration>
        </plugin>
        <plugin>
            <artifactId>maven-failsafe-plugin</artifactId>
            <version>2.18</version>
            <configuration>
                <includes>
                    <include>src/test/java/*.java </include>
                </includes>
            </configuration>
            <executions>
                <execution>
                    <goals>
                        <goal>integration-test</goal>
                        <goal>verify</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.2</version>
            <configuration>
                <source>1.8</source>
                <target>1.8</target>
            </configuration>
        </plugin>
        <plugin>
            <groupId>net.serenity-bdd.maven.plugins</groupId>
            <artifactId>serenity-maven-plugin</artifactId>
            <version>1.1.29-rc.1</version>
            <dependencies>
                <dependency>
                    <groupId>net.serenity-bdd</groupId>
                    <artifactId>serenity-core</artifactId>
                    <version>1.1.29-rc.3</version>
                </dependency>
            </dependencies>
            <executions>
                <execution>
                    <id>serenity-reports</id>
                    <phase>post-integration-test</phase>
                    <goals>
                        <goal>aggregate</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>
Caitlyn
  • 255
  • 2
  • 4
  • 7

3 Answers3

15

See POM Reference, Exclusions:

Exclusions explicitly tell Maven that you don't want to include the specified project that is a dependency of this dependency (in other words, its transitive dependency).

See also Apache Maven Enforcer Rules, Dependency Convergence:

If a project has two dependencies, A and B, both depending on the same artifact, C, this rule will fail the build if A depends on a different version of C then the version of C depended on by B.

[...]

And this will succeed.

   <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-jdk14</artifactId>
      <version>1.6.1</version>
    </dependency>
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-nop</artifactId>
      <version>1.6.0</version>
      <exclusions>
        <exclusion>
          <groupId>org.slf4j</groupId>
          <artifactId>slf4j-api</artifactId>
        </exclusion>
      </exclusions>
    </dependency>
Gerold Broser
  • 14,080
  • 5
  • 48
  • 107
13

I know I'm late to the party, but after scratching my head for 8-10 hours, I came around this solution which fixes the problem when you don't have control over different poms where the different versions of dependencies are used at different places. So, I thought it's worth sharing.

@Gerold's answer is an ideal one (source: Maven wiki). But, it works for the case when you are the owner of all the dependencies and have the time, luxury and write permission to fix the issue at the root. In my case, I was using a company-wide global parent pom which had different versions set in different places, so I was facing this issue. I wanted to find some way to fix this on my end without changing the global parent pom.

To fix this, in your project's parent pom, you can specify the exact version which matches with rest of the places and override the versions specified by the global parent poms at different places. You can add this block in your project's parent pom

<!-- ============================= -->
<!-- DEPENDENCY MANAGEMENT -->
<!-- ============================= -->
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>commons-collections</groupId>
            <artifactId>commons-collections</artifactId>
            <!-- This version should be consistent 
                 with versions at other places -->
            <version>3.2.2</version>
        </dependency>
    </dependencies>
</dependencyManagement>

HTH

avp
  • 2,892
  • 28
  • 34
  • 1
    Do be careful. I've observed that a user picking the one-true-version version (via depMan) *today* means that in future it will be a version used by *none* of the dependencies :) If you must use enforcer, `` are the correct (if ugly and terribly verbose) way of tracking the transitives of your key dependencies – drekbour May 21 '21 at 11:34
  • 1
    For those who want a bit more [docs on it](https://blogs.oracle.com/developers/post/mastering-maven-the-enforcer-plugin) – Ordiel Oct 06 '21 at 21:05
2

Or just remove the maven enforcer all together if you really/temporarily need to get past this issue.

JavaGeek
  • 475
  • 5
  • 14
  • Not convinced removing the check actually solves the issue. Importing two libraries at different versions can cause lots of runtime problems that are a lot harder to find and debug. The enforcer is actually useful in this case. – lcardito Nov 22 '19 at 09:37
  • 2
    Not convinced? Did you try what I suggested? It works in many cases and for many people that I talk to. Also I posted what worked for me giving people an alternate suggestion. Not sure why you disliked the comment. Dislikes are for answers that are incorrect which this answer is not. – JavaGeek Nov 23 '19 at 10:22
  • 3
    Disliked it because the suggested solution would not actually fix the root cause, rather simply hide it. I would not suggest to solve a problem by simply removing the cause, instead we should promote an understanding of the problem itself and point to a solution that fixes the root cause not just the surfaced symptom. – lcardito Nov 27 '19 at 11:55
  • Okay, you must not be used to American English dialect, but I just modified my comment to be more clear that if you really badly/temporarily want to get past the issue then you can remove the enforcer. Hope you can remove the dislike now! Because what I suggested is one of the viable options that works perfectly fine for some people just as it worked for me! – JavaGeek Nov 28 '19 at 14:50
  • JavaGeek's answer appears a bit harsh, but is actually correct and should be the accepted one. In this case the 1st level dependency `serenity-core:1.1.29-rc.3` does not fullfil "dependency convergence" itself, but has transitive dependencies of `commons-collections` in versions `3.2.1` and `3.2.2`. That's nothing you as a consumer should solve. Not even with an entry in your ´dependencyManagement` section. – Peter Wippermann Apr 09 '20 at 16:02
  • This is why I don't like enforcer. It's basically giving you the heads-up of a version conflict *that Maven already resolved* and then failing your build. Indeed runtime issues could occur in disparate cases (e.g. some OSS lib is a decade older than the others) but you do have tests right? – drekbour May 21 '21 at 11:31