java.lang.NoClassDefFoundError – 没有找到类定义错误
当在类路径中找不到所需的类时,java.lang.NoClassDefFoundError是运行时错误,因此JVM无法将其加载到内存中。
java.lang.NoClassDefFoundError -> java.lang.NoClassDefFoundError
- NoClassDefFoundError is a runtime error, so it’s beyond our application scope to anticipate and recover from this.
- java.lang.NoClassDefFoundError is a runtime error, it never comes in compile time.
- It’s very easy to debug NoClassDefFoundError because it clearly says that JVM was unable to find the required class, so check classpath configurations to make sure required classes are not missed.
找不到类定义错误的类图
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类,然后执行它,就像下面这样。
scdev:temp scdev$ ls
Data.java DataTest.java
scdev:temp scdev$ javac DataTest.java
scdev:temp scdev$ ls
Data.class Data.java DataTest.class DataTest.java
scdev:temp scdev$ java DataTest
Data Id = 10
scdev:temp scdev$
到目前为止一切都很好,现在让我们把Data类文件移到其他地方,然后尝试执行DataTest类。我们不会再次编译它,因为那样会导致编译错误。
scdev:temp scdev$ mv Data.java Data.class ../
scdev:temp scdev$ ls
DataTest.class DataTest.java
scdev:temp scdev$ 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
scdev:temp scdev$
如何解决java.lang.NoClassDefFoundError错误?
通过以上示例,我们可以明确地确定此错误的唯一原因是在编译时期所需的类是可用的,但在运行时却不可用。您可以通过检查以下内容来修复NoClassDefFoundError错误:
- Check the exception stack trace to know exactly which class throw the error and which is the class not found by java.
- Next step is to look for classpath configuration, sometimes we compile our classes in Eclipse or some other environment and run in some other environment and we can miss classpath configurations. For example, I can fix above issue easily by adding the directory which contains Data class to the classpath like below.
scdev:temp scdev$ java -classpath .:.. DataTest
Data Id = 10
scdev:tempRemember that earlier I had moved Data class to previous directory. - Most of the times, NoClassDefFoundError comes with applications running on some server as web application or web services, in that case check if the required jars are part of the WAR file or not. For example, below maven configuration will not package jar file when generating WAR file.
javax.servlet
servlet-api
3.0.1
provided
But we need it for creating a servlet based web application, usually this jar is always part of Tomcat or any other application server.
这就是对java.lang.NoClassDefFoundError的简要介绍,希望当你遇到这个错误时能够获取足够的想法,并且轻松地修复它。参考资料:API文档,Java中的异常处理。