How to override a transitive dependency version?

965 views Asked by At

Recently, I upgraded to Java 21 and noticed this error during build

Failed to enhance class ...:
  Java 21 (65) is not supported by the current version of Byte Buddy
  which officially supports Java 20 (64) - update Byte Buddy or set
  net.bytebuddy.experimental as a VM property

the issue is that I'm using Mockito 4 in my dependencies and it has dependency to earlier version of byte-buddy that doesn't support Java 21.

I tried to override the dependency to a newer version of byte-buddy as follow in my POM

...
<dependency>
    <groupId>org.mockito</groupId>
    <artifactId>mockito-core</artifactId>
    <version>${mockito.core.version}</version>
    <scope>test</scope>
    <exclusions>
        <exclusion>
            <groupId>net.bytebuddy</groupId>
            <artifactId>byte-buddy</artifactId>
        </exclusion>
    </exclusions>
</dependency>
<dependency>
    <groupId>net.bytebuddy</groupId>
    <artifactId>byte-buddy</artifactId>
    <version>1.14.11</version>
    <scope>test</scope>
</dependency>
...

but when I run the mvn dependency:tree I see this

[INFO] +- org.mockito:mockito-core:jar:4.0.0:test
[INFO] |  +- net.bytebuddy:byte-buddy-agent:jar:1.11.19:test
[INFO] |  \- org.objenesis:objenesis:jar:3.2:test
[INFO] +- net.bytebuddy:byte-buddy:jar:1.14.11:test 

So the override is not affecting Mockito's dependency.

Is there any way to change that other than upgrading Mockito to a newer version? (Assuming the newer version of byte-buddy works with current version of Mockito.)

2

There are 2 answers

1
kriegaex On

Just dependency-manage what you want to use in your project.

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>org.acme</groupId>
  <artifactId>dummy</artifactId>
  <version>1.0</version>

  <properties>
    <maven.compiler.source>8</maven.compiler.source>
    <maven.compiler.target>8</maven.compiler.target>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <byte-buddy.version>1.14.9</byte-buddy.version>
  </properties>

  <dependencyManagement>
    <dependencies>
      <dependency>
        <groupId>net.bytebuddy</groupId>
        <artifactId>byte-buddy</artifactId>
        <version>${byte-buddy.version}</version>
        <scope>test</scope>
      </dependency>
      <dependency>
        <groupId>net.bytebuddy</groupId>
        <artifactId>byte-buddy-agent</artifactId>
        <version>${byte-buddy.version}</version>
        <scope>test</scope>
      </dependency>
    </dependencies>
  </dependencyManagement>

  <dependencies>
    <dependency>
      <groupId>org.mockito</groupId>
      <artifactId>mockito-core</artifactId>
      <version>4.11.0</version>
      <scope>test</scope>
    </dependency>
  </dependencies>

</project>

Update: To show the difference between my approach and the one suggested by rekha sharma, let us check what the dependency tree looks like:

org.acme:dummy:jar:1.0
\- org.mockito:mockito-core:jar:4.11.0:test
   +- net.bytebuddy:byte-buddy:jar:1.14.9:test
   +- net.bytebuddy:byte-buddy-agent:jar:1.14.9:test
   \- org.objenesis:objenesis:jar:3.3:test

See? We did not change the dependency tree like in his answer. The tree stays the same, only the transitive dependency version was fixed. It only makes sense to add the Byte Buddy (BB) libraries, if the test code directly accesses classes from there. Otherwise, dependency:analyze would correctly report the BB libraries as unused, declared dependencies.

1
Rekha Sharma On

You just need to do mvn clean install after adding exclusion in mockito dependency in your pom.xml.

I tried it and it worked:

    <dependency>
        <groupId>org.mockito</groupId>
        <artifactId>mockito-core</artifactId>
        <version>4.5.1</version>
        <scope>test</scope>
        <exclusions>
            <exclusion>
                <groupId>net.bytebuddy</groupId>
                <artifactId>byte-buddy-agent</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    <dependency>
        <groupId>net.bytebuddy</groupId>
        <artifactId>byte-buddy</artifactId>
        <version>1.12.12</version>
        <scope>test</scope>
    </dependency>

Dependency tree after clean install : dependency tree after adding exclusion and running mvn clean install