Java Top

I just announced the new Learn Spring course, focused on the fundamentals of Spring 5 and Spring Boot 2:

>> CHECK OUT THE COURSE

1. Overview

In this tutorial, we'll look at the java.lang.NoSuchMethodError and some ways to handle it.

2. NoSuchMethodError

As the name suggests, the NoSuchMethodError occurs when a particular method is not found. This method can either be an instance method or a static method.

In most cases, we're able to catch this error at compile-time. Hence, it's not a big issue. However, sometimes it could be thrown at runtime, then finding it becomes a bit difficult. According to the Oracle documentation, this error may occur at runtime if a class has been incompatibly changed.

Hence, we may encounter this error in the following cases. Firstly, if we do just a partial recompilation of our code. Secondly, if there is version incompatibility with the dependencies in our application, such as the external jars.

Note that the NoSuchMethodError inheritance tree includes IncompatibleClassChangeError and LinkageError. These errors are associated with an incompatible class change after compilation.

3. Example of NoSuchMethodError

Let’s see this error in action with an example. For this, we'll create two classes. First is SpecialToday which will list the specials for the day in a restaurant: 

public class SpecialToday {
    private static String desert = "Chocolate Cake";

    public static String getDesert() {
        return desert;
    }
}

The second class MainMenu calls methods from SpecialsToday:

public class MainMenu {
    public static void main(String[] args) {
        System.out.println("Today's Specials: " + getSpecials());
    }

    public static String getSpecials() {
        return SpecialToday.getDesert();
    }
}

Here the output will be:

Today's Specials: Chocolate Cake

Next, we’ll delete the method getDesert() in SpecialToday and recompile only this updated class. This time when we run our MainMenu, we notice the following runtime error:

Exception in thread "main" java.lang.NoSuchMethodError: SpecialToday.getDesert()Ljava/lang/String;

4. How to Handle NoSuchMethodError

Now let's see how we can handle this. For the above code, let’s do a full clean-compile, including both the classes. We'll notice that the error will be caught while we're compiling. If we use an IDE like Eclipse, it will be detected even earlier, as soon as we update SpecialsToday.

Hence if we run into this error with our applications, as a first step, we'll do a full clean compile. With maven, we'll run the mvn clean install command.

Sometimes the issue is with the external dependencies of our application. In this case, we'll first check the order of the jars in the build path pulled by the classpath loader. And we'll trace and update the inconsistent jar.

However, if we still encounter this error at runtime, we'll have to dig deeper. We'll have to ensure that the Compile-time and the Runtime classes and jars have the same versions. For this, we can run the application with -verbose: class option to check the loaded classes. We can run the command as follows:

$ java -verbose:class com.baeldung.exceptions.nosuchmethoderror.MainMenu
[0.014s][info][class,load] opened: /usr/lib/jvm/java-11-openjdk-amd64/lib/modules
[0.015s][info][class,load] opened: /usr/share/java/java-atk-wrapper.jar
[0.028s][info][class,load] java.lang.Object source: shared objects file
[0.028s][info][class,load] java.io.Serializable source: shared objects file

Using this information about all the classes being loaded in the individual jars, during runtime, we can trace the incompatible dependency.

We should also make sure that there are no duplicate classes in two or more jars. In most cases, maven will help control conflicting dependencies directly. Furthermore, we can run the mvn dependency: tree command to get the dependency tree of our project as follows:

$ mvn dependency:tree
[INFO] Scanning for projects...
[INFO]
[INFO] -------------< com.baeldung.exceptions:nosuchmethoderror >--------------
[INFO] Building nosuchmethoderror 0.0.1-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- maven-dependency-plugin:2.8:tree (default-cli) @ nosuchmethoderror ---
[INFO] com.baeldung.exceptions:nosuchmethoderror:jar:0.0.1-SNAPSHOT
[INFO] \- org.junit:junit-bom:pom:5.7.0-M1:compile

We can check the libraries and their versions in the list generated by this command. Moreover, we can also manage dependencies using maven tags. Using the <exclusions> tag, we can exclude the problematic dependency. Using the <optional> tag, we can prevent unwanted dependencies from being bundled in the jar or war.

5. Conclusion

In this article, we addressed NoSuchMethodError. We discussed the cause of this error and also ways to handle it. For more details on how to handle errors properly, please refer to our article on catching Java errors.

As always, the code presented in this article is available over on GitHub.

Java bottom

I just announced the new Learn Spring course, focused on the fundamentals of Spring 5 and Spring Boot 2:

>> CHECK OUT THE COURSE
Comments are closed on this article!