← Debugging Guides

阅读中文版本

Java — NoSuchMethodError at runtime after a dependency change

Fix NoSuchMethodError by detecting duplicate dependency versions causing the wrong class to load.

advanceddebuggingjavadependencies

Symptoms

  • java.lang.NoSuchMethodError: some.Class.method(...)
  • The code compiled fine but fails at runtime
  • The error appears after upgrading one library
  • A method exists in source but not in the loaded jar

Possible causes

  • Two versions of the same library are on the classpath and the older one wins
  • An indirect dependency pins an older version
  • A shaded or relocated jar contains a conflicting class
  • The runtime classpath differs from the compile classpath

Diagnosis steps

Inspect the dependency tree

mvn dependency:tree -Dincludes=group:artifact

Interpretation

Multiple versions of the artifact reveal the conflict that lets an older class shadow the new one.

Ask where the class came from

java -verbose:class -cp app.jar Main 2>&1 | grep SomeClass

Interpretation

The loaded-from line names the jar providing the class, which is often not the version you expect.

Force a single version

mvn dependency:tree -Dverbose -Dincludes=group:artifact

Interpretation

Understanding the paths lets you exclude or pin one version so only the intended jar loads.

Root cause

The class loaded at runtime came from a different version of the library than the one compiled against, so a method that exists in source is absent in the loaded class.

Fix

Resolve the version conflict by excluding the unwanted transitive version or pinning one version in dependency management, then rebuild so compile and runtime classpaths agree.

Verify the fix

Run the application and confirm the method resolves, then inspect the dependency tree to confirm a single version of the library remains.

Symptom walkthrough

An application compiled successfully throws NoSuchMethodError at runtime, naming a method the source clearly calls. The method exists in one version of a library and not in another, and the runtime loaded the wrong jar because two versions ended up on the classpath. This is a classpath conflict, not a code error, so editing the calling code will not help.

Fix in practice

Inspect the dependency tree for duplicate versions, exclude or pin the unwanted transitive dependency, and rebuild so the compile and runtime classpaths match. Verify the class source with verbose class loading when the conflict is indirect or shaded.

Verification

Rerun the application and confirm the call resolves, then re-inspect the dependency tree to confirm only one version remains. A single resolved version plus a working call confirms the fix. A dependency convergence rule in the build prevents the same conflict from returning unnoticed.

Diagnostic commands

Check the behavior with commands like these:

mvn dependency:tree -Dincludes=group:artifact
java -verbose:class -cp app.jar Main 2>&1 | grep SomeClass
mvn dependency:tree -Dverbose -Dincludes=group:artifact