java.lang.NoSuchMethodError示例

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。 该方法可以是静态的,也可以是实例方法。

java.lang.NoSuchMethodError (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.

大多数时候, java.lang.NoSuchMethodError被编译器捕获,但是有时它可能在运行时发生。 如果在运行时发生此错误,则唯一的原因可能是类结构的更改导致其不兼容。

Let’s try to raise this error at runtime. So we have two classes Data and Temp as shown below.

让我们尝试在运行时引发此错误。 因此,我们有两个类DataTemp ,如下所示。

public class Data {

	public void foo() {
		System.out.println("foo");
	}
	
	public void bar() {
 		System.out.println("bar");
 	}
}
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.

两个程序看起来都不错,让我们编译并通过命令行运行它们。 请注意,稍后我将更改Data类时,我没有使用Eclipse或任何其他IDE来避免对该错误进行编译时检测。

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.

因此程序执行良好,让我们继续进行操作,如下所示更改Data类定义。

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.

注意,我删除了bar()方法。 现在我们只需要编译Data类,而不编译主类。

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.

如您所见,由于Data类与Temp类不兼容,因此出现了java.lang.NoSuchMethodError 。 如果我们尝试编译Data类,则将出现编译时错误,如下所示。

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$

Tomcat中的java.lang.NoSuchMethodError (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;

大多数情况下,您会在某些依赖项很多的应用程序中看到java.lang.NoSuchMethodError 。 这有两个主要原因。

  1. 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.

    编译时使用的Jar版本与运行时不同。 例如,您的应用程序中MySQL jar的版本可能与Tomcat lib文件夹中的版本不同。 由于Java Classloader首先查看tomcat lib文件夹jar,因此如果在加载的类中未找到任何方法,则有可能出现java.lang.NoSuchMethodError
  2. 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

    由于类名相同而发生冲突。 例如,您的应用程序正在使用某些第三方jar,该第三方jar与您的完全相同的类名。 因此,如果classloader从其他jar加载类,则在运行时会收到java.lang.NoSuchMethodError

调试java.lang.NoSuchMethodError (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.

您可以使用Java运行时选项-verbose:class来获取有关用于加载类的jar的信息。 您可以在tomcat catalina.sh或setenv.sh中设置此配置,如下所示。

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.

然后,您将看到类似以下的日志,这对弄清加载类时使用的实际jar以及运行时出现java.lang.NoSuchMethodError的原因非常有帮助。

[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.

这就是java.lang.NoSuchMethodError示例以及检测和修复它的提示。 希望对您摆脱该错误有帮助。

Reference: API Document

参考: API文档

翻译自: https://www.journaldev.com/14538/java-lang-nosuchmethoderror

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值