Skip to content

Fix: Java NoSuchMethodError

FixDevs ·

Quick Answer

How to fix Java NoSuchMethodError caused by classpath conflicts, incompatible library versions, wrong dependency scope, shaded JARs, and compile vs runtime version mismatches.

The Error

You run a Java application and get:

Exception in thread "main" java.lang.NoSuchMethodError:
'void com.google.gson.GsonBuilder.setStrictness(com.google.gson.Strictness)'

Or variations:

java.lang.NoSuchMethodError: org.apache.commons.lang3.StringUtils.isBlank(Ljava/lang/CharSequence;)Z
java.lang.NoSuchMethodError: 'java.util.List com.example.UserService.findAll()'
NoSuchMethodError: 'void org.slf4j.Logger.atDebug()'

The JVM found the class but the method you are calling does not exist in it. The code was compiled against one version of a library but is running with a different version that does not have that method.

Why This Happens

Java compiles method calls into bytecode that references the exact method signature (name, parameter types, return type). At runtime, the JVM loads the class and looks for that exact method. If the runtime class has a different version than the compile-time class, the method might not exist.

This is different from ClassNotFoundException (class not found at all) and NoClassDefFoundError (class found at compile time but missing at runtime). With NoSuchMethodError, the class is found but the specific method is missing.

Common causes:

  • Dependency version conflict. Two libraries require different versions of the same dependency, and Maven/Gradle picks the wrong one.
  • Stale compiled classes. You updated a dependency but did not recompile the code that uses it.
  • Shaded/fat JAR conflict. A shaded JAR bundles an old version of a library that conflicts with a newer version on the classpath.
  • Classpath ordering. The wrong version of a JAR is loaded first.
  • JDK version mismatch. A method exists in JDK 17 but not in JDK 11.

Fix 1: Find the Conflicting Dependency

Identify which version of the library is actually being loaded at runtime:

Maven — show the dependency tree:

mvn dependency:tree

Look for the library mentioned in the error. If you see multiple versions:

[INFO] +- com.example:my-app:jar:1.0
[INFO] |  +- com.google.code.gson:gson:jar:2.8.9:compile
[INFO] +- com.other:library:jar:2.0
[INFO] |  +- com.google.code.gson:gson:jar:2.10.1:compile (version managed from 2.8.9)

Gradle — show dependencies:

./gradlew dependencies --configuration runtimeClasspath

Find which JAR is loaded at runtime:

System.out.println(SomeClass.class.getProtectionDomain().getCodeSource().getLocation());

This prints the JAR path that contains the class, revealing which version is loaded.

Pro Tip: Always check the runtime classpath, not just the compile classpath. A method might exist at compile time but the runtime classpath loads a different version. Use -verbose:class JVM flag to see which classes are loaded from which JARs:

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

Fix 2: Force the Correct Dependency Version

Maven — use <dependencyManagement>:

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
            <version>2.10.1</version>
        </dependency>
    </dependencies>
</dependencyManagement>

This forces all transitive dependencies to use version 2.10.1.

Maven — exclude the wrong version:

<dependency>
    <groupId>com.other</groupId>
    <artifactId>library</artifactId>
    <version>2.0</version>
    <exclusions>
        <exclusion>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
        </exclusion>
    </exclusions>
</dependency>

Then add the correct version as a direct dependency.

Gradle — force a version:

configurations.all {
    resolutionStrategy {
        force("com.google.code.gson:gson:2.10.1")
    }
}

Gradle — exclude:

implementation("com.other:library:2.0") {
    exclude(group = "com.google.code.gson", module = "gson")
}

For Maven dependency resolution errors, see Fix: Maven could not resolve dependencies.

Fix 3: Clean and Rebuild

Stale compiled classes can cause NoSuchMethodError when the dependency changed but your code was not recompiled:

Maven:

mvn clean package

Gradle:

./gradlew clean build

IntelliJ IDEA:

Build → Rebuild Project (not just Build, which is incremental).

Delete build caches manually:

rm -rf target/        # Maven
rm -rf build/         # Gradle
rm -rf out/           # IntelliJ
rm -rf ~/.gradle/caches/  # Gradle global cache (nuclear option)

Common Mistake: Running mvn package without clean after changing dependency versions. Maven’s incremental compilation does not always recompile classes affected by dependency changes. Always use mvn clean package when dependency versions change.

Fix 4: Check for Shaded JAR Conflicts

Shaded (fat/uber) JARs bundle dependencies inside them. If a shaded JAR contains an old version of a library, it conflicts with the correct version on the classpath:

Diagnose:

# List classes in a JAR
jar tf my-shaded-app.jar | grep "gson"

If the shaded JAR contains com/google/gson/GsonBuilder.class, it is bundling Gson. The shaded copy might be an older version.

Fix: Relocate packages in the shade plugin:

Maven Shade Plugin:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-shade-plugin</artifactId>
    <configuration>
        <relocations>
            <relocation>
                <pattern>com.google.gson</pattern>
                <shadedPattern>shaded.com.google.gson</shadedPattern>
            </relocation>
        </relocations>
    </configuration>
</plugin>

Relocation moves the bundled classes to a different package, preventing conflicts with the non-shaded version.

Fix 5: Fix JDK Method Availability

Some methods only exist in newer JDK versions:

// Java 11+ only:
String result = "  hello  ".strip();

// Java 9+ only:
List<String> list = List.of("a", "b", "c");

// Java 16+ only:
record User(String name, int age) {}

Check your runtime JDK version:

java -version

Fix: Update the JDK to match the version the code was compiled for. See Fix: Java UnsupportedClassVersionError for JDK version management.

Fix: Use compatible alternatives for older JDKs:

// Instead of String.strip() (Java 11+):
String result = "  hello  ".trim();  // Java 1.0+

// Instead of List.of() (Java 9+):
List<String> list = Arrays.asList("a", "b", "c");  // Java 5+
List<String> list = Collections.unmodifiableList(Arrays.asList("a", "b", "c"));

Fix 6: Fix Spring Boot Dependency Conflicts

Spring Boot manages dependency versions through its BOM (Bill of Materials). Overriding a managed version can cause NoSuchMethodError:

Check Spring Boot’s managed versions:

mvn help:effective-pom | grep "gson"

Override safely with Spring Boot properties:

<properties>
    <gson.version>2.10.1</gson.version>
</properties>

Spring Boot property overrides are the safest way to change managed dependency versions because they update all related dependencies consistently.

Do NOT force incompatible versions:

If Spring Boot 3.x manages Jackson 2.15 and you force Jackson 2.10, Spring’s own code might call methods that only exist in 2.15. Stick to compatible version ranges.

Fix 7: Debug with Reflection

When the error message is unclear about which method is missing, use reflection to check:

import java.lang.reflect.Method;

for (Method method : SomeClass.class.getDeclaredMethods()) {
    System.out.println(method);
}

This lists all methods available in the class at runtime. Compare with what your code expects to find the mismatch.

Check the exact method signature:

try {
    Method m = SomeClass.class.getMethod("methodName", String.class, int.class);
    System.out.println("Found: " + m);
} catch (NoSuchMethodException e) {
    System.out.println("Method not found!");
    // List available methods for debugging
    for (Method m : SomeClass.class.getMethods()) {
        if (m.getName().contains("method")) {
            System.out.println("  Available: " + m);
        }
    }
}

Fix 8: Fix Test vs Runtime Classpath

A method might exist in the test classpath but not in the runtime classpath, or vice versa:

Maven scope issues:

<!-- This is only available during tests: -->
<dependency>
    <groupId>org.mockito</groupId>
    <artifactId>mockito-core</artifactId>
    <scope>test</scope>
</dependency>

If a class from a test-scoped dependency is accidentally used in production code, it compiles but fails at runtime with NoSuchMethodError or ClassNotFoundException.

Fix: Check dependency scopes:

mvn dependency:tree -Dscope=runtime
mvn dependency:tree -Dscope=test

Compare the two trees to find dependencies that are only in the test scope.

Still Not Working?

Check for class loading order. In application servers (Tomcat, JBoss, WildFly), the class loading order differs from standalone applications. The server might load its own version of a library before yours.

Check for OSGi bundle issues. In OSGi environments (Eclipse, Karaf), each bundle has its own classloader. A method might be available in one bundle’s classloader but not another’s.

Check for annotation processor issues. Annotation processors (Lombok, MapStruct) generate code at compile time. If the processor version does not match the runtime library version, generated code might reference methods that do not exist.

Check for Java module system (JPMS) restrictions. In Java 9+, the module system can restrict access to methods. Add --add-opens or --add-exports flags if needed.

If the class itself is not found (rather than a specific method), see Fix: Java ClassNotFoundException. If the JVM runs out of memory during class loading, see Fix: Java OutOfMemoryError.

For Gradle build failures that prevent the application from running, see Fix: Gradle build failed.

F

FixDevs

Solo developer based in Japan. Every solution is cross-referenced with official documentation and tested before publishing.

Was this article helpful?

Related Articles