java.lang.NoClassDefFoundError

时间:2020-02-23 14:36:40  来源:igfitidea点击:

java.lang.NoClassDefFoundError是在类路径中找不到所需的类时抛出的运行时错误,因此JVM无法将其加载到内存中。

java.lang.NoClassDefFoundError

  • NoClassDefFoundError是运行时错误,因此超出预期范围并可以从中恢复。

  • java.lang.NoClassDefFoundError是运行时错误,它永远不会在编译时出现。

  • 调试NoClassDefFoundError非常容易,因为它明确指出JVM无法找到所需的类,因此请检查类路径配置以确保不会丢失所需的类。

NoClassDefFoundError类图

下图显示了" NoClassDefFoundError"类图及其超类。

如您所见,它的超类是Throwable和Error。

java.lang.NoClassDefFoundError原因

让我们首先尝试复制一个在运行时出现NoClassDefFoundError的情况。
假设我们有一个类似下面的java类。

public class Data {

	private int id;

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}
	
}

请注意,上面的类不依赖于任何其他自定义Java类,它仅使用Java内置类。
让我们创建另一个将在同一目录中使用Data类的类。

public class DataTest {

	public static void main(String[] args) {
		Data data = new Data();
		data.setId(10);
		System.out.println("Data Id = "+data.getId());
	}

}

现在,编译DataTest类,然后按如下所示执行它。

hyman:temp hyman$ls
Data.java	DataTest.java
hyman:temp hyman$javac DataTest.java 
hyman:temp hyman$ls 
Data.class	Data.java	DataTest.class	DataTest.java
hyman:temp hyman$java DataTest
Data Id = 10
hyman:temp hyman$

到目前为止,一切都很好,现在让我们将Data类文件移动到其他地方,然后尝试执行DataTest类。
从那时起,我们将不再编译它,因为它会导致编译错误。

hyman:temp hyman$mv Data.java Data.class ../
hyman:temp hyman$ls
DataTest.class	DataTest.java
hyman:temp hyman$java DataTest
Exception in thread "main" java.lang.NoClassDefFoundError: Data
	at DataTest.main(DataTest.java:5)
Caused by: java.lang.ClassNotFoundException: Data
	at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
	at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:335)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
	... 1 more
hyman:temp hyman$

其中我们得到了NoClassDefFoundError,因为java运行时无法找到Data类,如异常堆栈跟踪中清楚显示的那样。
下图显示了以上所有命令,并在终端窗口中输出。

如何解决java.lang.NoClassDefFoundError?

从上面的示例中,我们可以清楚地识别出此错误的唯一原因是所需的类在编译时可用,而在运行时不可用。
您可以通过检查以下内容来修复NoClassDefFoundError错误:

  • 检查异常堆栈跟踪以确切知道哪个类引发错误,哪个是Java找不到的类。

  • 下一步是寻找类路径配置,有时我们在Eclipse或者其他环境中编译我们的类并在其他环境中运行,我们可能会错过类路径配置。
    例如,我可以通过将包含Data类的目录添加到类路径中来轻松解决上述问题,如下所示。

请记住,之前我已经将Data类移动到了先前的目录。

  • 在大多数情况下,NoClassDefFoundError附带了作为Web应用程序或者Web服务在某些服务器上运行的应用程序,在这种情况下,请检查所需的jar是否是WAR文件的一部分。
    例如,以下Maven配置在生成WAR文件时不会打包jar文件。

但是我们需要它来创建基于servlet的Web应用程序,通常,此jar始终是Tomcat或者任何其他应用程序服务器的一部分。