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 类,然后像下面这样执行它。
pankaj:temp pankaj$ ls
Data.java DataTest.java
pankaj:temp pankaj$ javac DataTest.java
pankaj:temp pankaj$ ls
Data.class Data.java DataTest.class DataTest.java
pankaj:temp pankaj$ java DataTest
Data Id = 10
pankaj:temp pankaj$
到目前为止一切都很好,现在让我们将数据类文件移动到其他地方,然后尝试执行 DataTest 类。我们不会再次编译它,因为那样会给出编译错误。
pankaj:temp pankaj$ mv Data.java Data.class ../
pankaj:temp pankaj$ ls
DataTest.class DataTest.java
pankaj:temp pankaj$ 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
pankaj:temp pankaj$
就是这样,我们得到了这个错误,NoClassDefFoundError
因为 java 运行时无法找到Data
类,这在异常堆栈跟踪中清晰可见。下图显示了终端窗口中的所有上述命令和输出。
如何解决 java.lang.NoClassDefFoundError?
从上面的例子中,我们可以清楚地识别出此错误的唯一原因是所需的类在编译时可用,但在运行时不可用。您可以通过检查以下内容来修复 NoClassDefFoundError 错误:
-
检查异常堆栈跟踪以确切了解哪个类抛出了错误以及哪个类是 java 未找到的类。
-
下一步是查找类路径配置,有时我们在 Eclipse 或其他环境中编译类并在其他环境中运行,我们可能会错过类路径配置。例如,我可以通过像下面这样将包含数据类的目录添加到类路径来轻松解决上述问题。
pankaj:temp pankaj$ java -classpath .:.. DataTest Data Id = 10 pankaj:temp
请记住,我之前已将数据类移至了上一个目录。
-
大多数情况下,NoClassDefFoundError 会在某些服务器上作为Web 应用程序或 Web 服务运行时出现,在这种情况下,请检查所需的 jar 是否是 WAR 文件的一部分。例如,下面的 maven 配置在生成 WAR 文件时不会打包 jar 文件。
<dependency> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> <version>3.0.1</version> <scope>provided</scope> </dependency>
但是我们需要它来创建基于servlet的 Web 应用程序,通常这个 jar 始终是 Tomcat 或任何其他应用程序服务器的一部分。
以上就是快速浏览的全部内容java.lang.NoClassDefFoundError
,希望您能够了解此错误何时出现以及如何轻松修复它。参考:API 文档、Java 中的异常处理