java.lang.NoSuchMethodError is being thrown when program tries to call a class method that doesn’t exist. The method can be static or it can be an instance method too.
java.lang.NoSuchMethodError
Most of the times java.lang.NoSuchMethodError
is caught be compiler but sometimes it can occur at runtime. If this error occurs at runtime then the only reason could be the change in the class structure that made it incompatible.
Let’s try to raise this error at runtime. So we have two classes Data
and Temp
as shown below.
1 2 3 4 5 6 7 8 9 10 |
public class Data { public void foo() { System.out.println("foo"); } public void bar() { System.out.println("bar"); } } |
1 2 3 4 5 6 7 8 9 |
public class Temp { public static void main(String[] args) { Data d = new Data(); d.foo(); d.bar(); } } |
Both the programs look fine, let’s compile and run them through command line. Note that I am not using Eclipse or any other IDE to avoid compile time detection of this error when I will change the Data
class later on.
1 2 3 4 5 6 7 8 |
pankaj:Downloads pankaj$ javac Data.java pankaj:Downloads pankaj$ javac Temp.java pankaj:Downloads pankaj$ java Temp foo bar pankaj:Downloads pankaj$ |
So program executed fine, let’s go ahead and change Data class definition as shown below.
1 2 3 4 5 6 7 8 9 10 |
public class Data { public void foo() { System.out.println("foo"); } // public void bar() { // System.out.println("bar"); // } } |
Notice that I have removed bar()
method. Now we will have to compile only Data class, don’t compile the main class.
1 2 3 4 5 6 7 8 |
pankaj:Downloads pankaj$ javac Data.java pankaj:Downloads pankaj$ java Temp foo Exception in thread "main" java.lang.NoSuchMethodError: Data.bar()V at Temp.main(Temp.java:7) pankaj:Downloads pankaj$ |
As you can see that we have got the java.lang.NoSuchMethodError
because the Data class became incompatible with Temp class. If we would have tried to compile Data
class, we would have got compile time error as shown below.
1 2 3 4 5 6 7 8 9 10 |
pankaj:Downloads pankaj$ javac Temp.java Temp.java:7: error: cannot find symbol d.bar(); ^ symbol: method bar() location: variable d of type Data 1 error pankaj:Downloads pankaj$ |
java.lang.NoSuchMethodError in Tomcat
Most of the time you will see java.lang.NoSuchMethodError
in some applications with many dependencies. There are two main reasons for that;
- Jar version used at the compile time is different from the runtime. For example, you might have MySQL jar in your application having different version from what is present in Tomcat lib folder. Since tomcat lib folder jars are looked first by Java Classloader, there is a chance of
java.lang.NoSuchMethodError
if any method is not found in the class loaded. - Conflict because of same class name. For example, your application is using some third party jar which has same fully qualified class name as yours. So if classloader loads the class from other jar, you will get
java.lang.NoSuchMethodError
at runtime
Debugging java.lang.NoSuchMethodError
You can use java runtime option -verbose:class
to get the information about the jar that is used to load a class. You can set this configuration in tomcat catalina.sh or setenv.sh like below.
1 2 3 |
JAVA_OPTS="$JAVA_OPTS -verbose:class" |
Then you will see logs like below that is very helpful to figure out the actual jar used in loading a class and the reason for java.lang.NoSuchMethodError at runtime.
1 2 3 4 5 6 |
[Opened /Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home/jre/lib/rt.jar] [Loaded java.lang.Object from /Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home/jre/lib/rt.jar] [Loaded java.io.Serializable from /Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home/jre/lib/rt.jar] [Loaded com.journaldev.spring.controller.HomeController from file:/Users/pankaj/Downloads/apache-tomcat-8.5.16/webapps/spring-mvc-example/WEB-INF/classes/] |
That’s all for java.lang.NoSuchMethodError example and tips to detect and fix it. I hope it will be helpful to you in getting rid of this error.
Reference: API Document