java.lang.NoClassDefFoundError
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或者任何其他应用程序服务器的一部分。