Maven Dependency Version Conflict Fix
In this tutorial, you'll learn about Maven Dependency Version Conflict Fix. We cover key concepts, practical examples, and best practices.
Your Maven build fails with javax.xml.bind.JAXBException at runtime or ClassNotFoundException — two dependencies pull different versions of the same transitive library, causing runtime incompatibilities.
Step-by-Step Fix
1. View the dependency tree
# Wrong: guessing which version is being used
# Right: use the dependency tree to see conflicts
mvn dependency:tree -Dverbose
# Filter for a specific dependency
mvn dependency:tree -Dincludes=com.google.guava:guava
Expected output:
[INFO] com.mycompany:my-app:jar:1.0.0
[INFO] +- com.squareup.okhttp3:okhttp:jar:4.12.0:compile
[INFO] | \- com.squareup.okio:okio:jar:3.6.0:compile
[INFO] \- com.squareup.retrofit2:retrofit:jar:2.9.0:compile
[INFO] \- com.squareup.okhttp3:okhttp:jar:3.14.9:compile (version managed from 3.14.9 to 4.12.0)
2. Use dependency management to pin versions
<!-- Wrong: no dependency management, Maven uses nearest-wins strategy -->
<project>
<dependencies>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>31.1-jre</version>
</dependency>
<!-- Another dependency pulls in guava 30.0 -->
</dependencies>
</project>
<!-- Right: use dependencyManagement to pin versions -->
<project>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>32.1.3-jre</version>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<!-- Version inherited from dependencyManagement -->
</dependency>
</dependencies>
</project>
3. Exclude transitive dependencies
<!-- Wrong: conflicting transitive dependency from multiple sources -->
<project>
<dependencies>
<dependency>
<groupId>com.squareup.retrofit2</groupId>
<artifactId>retrofit</artifactId>
<version>2.9.0</version>
<!-- Pulls in okhttp 3.x, conflicting with okhttp 4.x below -->
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>4.12.0</version>
</dependency>
</dependencies>
</project>
<!-- Right: exclude the transitive dependency -->
<project>
<dependencies>
<dependency>
<groupId>com.squareup.retrofit2</groupId>
<artifactId>retrofit</artifactId>
<version>2.9.0</version>
<exclusions>
<exclusion>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>4.12.0</version>
</dependency>
</dependencies>
</project>
4. Use a BOM for consistent versions
<!-- Import a Bill of Materials to manage versions consistently -->
<project>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.fasterxml.jackson</groupId>
<artifactId>jackson-bom</artifactId>
<version>2.16.1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>3.2.1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<!-- Versions managed by BOM -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
</project>
5. Check for duplicate classes
# Check for duplicate/multiple versions of the same class on classpath
mvn dependency:tree -Dincludes=javax.xml.bind
# Or check specific packages
mvn help:effective-pom
6. Use enforcer plugin to detect conflicts
<project>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<version>3.4.1</version>
<executions>
<execution>
<id>enforce-dependency-convergence</id>
<goals><goal>enforce</goal></goals>
<configuration>
<rules>
<dependencyConvergence/>
<bannedDependencies>
<excludes>
<exclude>commons-logging:*</exclude>
</excludes>
</bannedDependencies>
</rules>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Prevention
- Always run
mvn dependency:treeto understand your full dependency graph. - Use
dependencyManagementto pin critical dependency versions. - Use BOM files from framework providers (Spring Boot, Jackson, AWS SDK).
- Use the Maven Enforcer plugin's
dependencyConvergencerule. - Exclude unnecessary transitive dependencies explicitly.
Common Mistakes with dependency tree
- Mixing let bindings with <- bindings in do notation, producing type errors
- Overlapping type class instances that cause GHC to reject the program with ambiguous dispatch errors
- Non-exhaustive pattern matches that compile with warnings then crash at runtime
These mistakes appear frequently in real-world MAVEN code. DodaTech's contributors have identified these patterns through analysis of open-source projects and production systems.
Practice Exercise
Write a pure function that safely divides two integers using Maybe, then test it with edge cases like division by zero and negative numbers.
This exercise reinforces the concepts covered in this guide. Try implementing it before checking online solutions.
FAQ
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro