Maven NoSuchMethodError — Dependency Version Conflict
Fix NoSuchMethodError and NoClassDefFoundError from conflicting transitive dependencies by inspecting the dependency tree and pinning via dependencyManagement.
Symptoms
- Runtime throws NoSuchMethodError or NoClassDefFoundError although it compiles
- The error names a method that exists in a newer version of a library
- Behavior differs between the IDE and the packaged jar
Possible causes
- Two versions of the same library are on the classpath and the older wins
- Maven nearest-wins mediation picks a transitive version you did not expect
- A shaded or relocated dependency was not relocated in the final artifact
Diagnosis steps
Inspect the dependency tree for duplicates
mvn dependency:tree -Dincludes=com.google.guava:guavaInterpretation
Multiple nodes for one artifact with different versions reveal the conflict.
Find who pulls the older version
mvn dependency:tree -Dverbose | grep -B 3 "guava:jar:20"Interpretation
The verbose tree shows omitted versions and the path that introduced them.
Verify what is on the runtime classpath
mvn dependency:build-classpath -Dmdep.outputFile=cp.txt && grep -o "guava[^:]*" cp.txtInterpretation
The actual runtime classpath, not the IDE, determines which version loads.
Root cause
Maven resolves a single version per artifact using nearest-wins (and first-declared on ties). A transitive older version can therefore override your direct newer one, so code compiled against the newer API fails at runtime with NoSuchMethodError.
Fix
Pin the version with dependencyManagement or a direct dependency, exclude the offending transitive path, and rebuild the tree to confirm one version remains.
Risk note
Pinning a version that other libraries depend on can break their API expectations; verify each consumer after pinning.
Verify the fix
Rebuild the tree and confirm exactly one version resolves; run the failing code path and confirm no NoSuchMethodError, then run the full test suite.
Symptoms
When you hit “Maven NoSuchMethodError — Dependency Version Conflict”, guessing wastes time. The guide below follows evidence: reproduce the symptom, run targeted diagnostics, identify the root cause, apply the fix, and verify it with concrete checks.
Observed symptoms include:
- Runtime throws NoSuchMethodError or NoClassDefFoundError although it compiles
- The error names a method that exists in a newer version of a library
- Behavior differs between the IDE and the packaged jar
Reproduce and Diagnose
Reproduce the failure in isolation before changing any code. Work through the checks below in order; each one narrows the search space.
Step 1: Inspect the dependency tree for duplicates
mvn dependency:tree -Dincludes=com.google.guava:guava
Multiple nodes for one artifact with different versions reveal the conflict.
Step 2: Find who pulls the older version
mvn dependency:tree -Dverbose | grep -B 3 "guava:jar:20"
The verbose tree shows omitted versions and the path that introduced them.
Step 3: Verify what is on the runtime classpath
mvn dependency:build-classpath -Dmdep.outputFile=cp.txt && grep -o "guava[^:]*" cp.txt
The actual runtime classpath, not the IDE, determines which version loads.
Likely contributors, in order of frequency:
- Two versions of the same library are on the classpath and the older wins
- Maven nearest-wins mediation picks a transitive version you did not expect
- A shaded or relocated dependency was not relocated in the final artifact
Root Cause
Maven resolves a single version per artifact using nearest-wins (and first-declared on ties). A transitive older version can therefore override your direct newer one, so code compiled against the newer API fails at runtime with NoSuchMethodError.
The Fix
Pin the version with dependencyManagement or a direct dependency, exclude the offending transitive path, and rebuild the tree to confirm one version remains.
Watch out: Pinning a version that other libraries depend on can break their API expectations; verify each consumer after pinning.
<!-- pom.xml: force a single, known-good version -->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>33.0.0-jre</version>
</dependency>
</dependencies>
</dependencyManagement>
<!-- or exclude the offending transitive path -->
<exclusions>
<exclusion>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</exclusion>
</exclusions>
Verify and Prevent
Rebuild the tree and confirm exactly one version resolves; run the failing code path and confirm no NoSuchMethodError, then run the full test suite.
Once verified, add a regression test that reproduces the original symptom so the failure cannot silently return.
This class of failure is usually environmental rather than pure logic, so capture the exact command, the environment variables, and the working directory in your bug report. Reproduce it in the smallest possible script, then widen the scope only once the minimal case is understood. A short written checklist for this failure mode saves hours the next time it appears.