当前位置: 首页 > 知识库问答 >
问题:

NoClassDefoundError和ClassNotFoundException之间的区别是什么?

谯英彦
2023-03-14

NoClassDefoundErrClassNotFoundException之间有什么区别?

是什么原因导致他们被扔?如何解决这些问题?

在修改现有代码以包含新的jar文件时,我经常会遇到这些可抛物。我在通过WebStart发布的一个Java应用程序的客户端和服务器端都碰到了它们。

我遇到的可能原因是:

  1. 代码客户端的build.xml中未包含的包
  2. 我们正在使用的新JAR缺少运行时类路径
  3. 版本与以前的JAR冲突

当我今天遇到这些问题时,我会采取跟踪和错误的方法来使事情正常工作。我需要更多的清晰和理解。

共有2个答案

秦涵涤
2023-03-14

当类加载器找不到报告的类时,将引发ClassNotFoundException。这通常意味着类路径中缺少该类。这也可能意味着有问题的类试图从另一个类加载,而另一个类是在父类加载器中加载的,因此子类加载器中的类不可见。当工作在更复杂的环境中(如应用服务器)时,有时会出现这种情况(WebSphere因此类类加载器问题而臭名昭著)。

人们往往会将java.lang.NoClassDefoundErrjava.lang.ClassNotFoundException混淆,但这有一个重要的区别。例如,一个异常(实际上是一个错误,因为java.lang.NoClassDefounderRor是java.lang.error的子类)类似

java.lang.NoClassDefFoundError:
org/apache/activemq/ActiveMQConnectionFactory

并不意味着ActiveMQConnectionFactory类不在类路径中。事实上恰恰相反。这意味着类加载器找到了类ActiveMQConnectionFactory,但在尝试加载该类时,它在读取类定义时遇到错误。当所讨论的类具有静态块或成员时,通常会发生这种情况,这些静态块或成员使用了类加载器未找到的类。因此,要找到罪魁祸首,请查看相关类的源(本例中为ActiveMQConnectionFactory)并查找使用静态块或静态成员的代码。如果您没有访问源代码,那么只需使用JAD反编译它。

在检查代码时,假设您发现了如下所示的代码行,确保类SomeClass在您的类路径中。

private static SomeClass foo = new SomeClass();

提示:要找出一个类属于哪个jar,可以使用web站点jarFinder。这允许您使用通配符指定类名,并在其JAR数据库中搜索该类。jarhoo允许您做同样的事情,但它不再免费使用。

如果您想在本地路径中找到类所属的jar,可以使用jarscan这样的实用程序(http://www.inetfeedback.com/jarscan/)。您只需指定您想要定位的类和您想要它开始在JAR和zip文件中搜索类的根目录路径。

岳浩穰
2023-03-14

与Java API规范的区别如下。

对于ClassNotFoundException:

当应用程序尝试通过类的字符串名加载类时引发:

  • class中的forName方法。
  • ClassLoader中的FindSystemClass方法。
  • ClassLoader中的LoadClass方法。

但找不到具有指定名称的类的定义。

对于NoClassDefoundError:

如果Java虚拟机或classloader实例尝试加载类的定义(作为正常方法调用的一部分或作为使用新表达式创建新实例的一部分),但找不到该类的定义,则引发。

在编译当前正在执行的类时,已搜索到的类定义存在,但再也找不到该定义。

因此,当源代码成功编译,但在运行时找不到所需的文件时,似乎会出现NoClassDefoundError。这可能会发生在JAR文件的分发或生成中,其中没有包含所有必需的class文件。

至于ClassNotFoundException,它似乎可能源于试图在运行时对类进行反射调用,但程序试图调用的类并不存在。

两者的区别在于,一个是错误而另一个是异常NoClassDefoundErr是一个error,它产生于Java虚拟机在查找它希望查找的类时遇到问题。由于找不到class文件,或者与编译时生成或遇到的文件不相同,预期在编译时工作的程序无法运行。这是一个非常严重的错误,因为JVM无法启动程序。

另一方面,ClassNotFoundException是一个Exception,因此它在某种程度上是预期的,并且是可恢复的。使用反射是很容易出错的(因为有一些预期,事情可能不会按照预期进行。没有编译时检查,以查看所有所需的类是否存在,所以在运行时查找所需的类时会出现任何问题)。

 类似资料:
  • 问题内容: NoClassDefFoundError和ClassNotFoundException之间有什么区别? 问题答案: 与Java API规范的区别如下。 对于ClassNotFoundException: 当应用程序尝试使用其字符串名称通过其字符串名称加载类时抛出: 类中的方法。 类中的方法。 类中的方法。 但找不到具有指定名称的类的定义。 对于NoClassDefFoundError:

  • ClassNotFoundException和NoClassDefFoundError之间有什么区别? 谁能举个例子来解释。。

  • 问题内容: 和之间有什么区别? 是什么导致它们被抛出?如何解决? 在修改现有代码以包含新的jar文件时,我经常遇到这些throwables。我在客户端和服务器端都通过Webstart分发了一个Java应用程序。 我遇到的可能原因: build.xml代码客户端未包含的软件包 我们正在使用的新jar缺少运行时类路径 版本与先前的jar冲突 今天,当我遇到这些问题时,我会采取一种犯错的方法来使事情正常

  • 在Java 7之前,JVM内存中有一个名为PermGen的区域,JVM以前在这里保存它的类。在Java 8中,它被移除并被称为元空间的区域所取代。 PermGen和Metaspace之间最重要的区别是什么? 我知道的唯一区别是,并且忽略了VM参数。

  • 当我试图在Spring4.x上进行测试时,我使用了MockMvc web客户端,但我正在阅读和尝试Spring5.x的新特性。 我认为,WebTestClient和MockMvc是相同或非常相似的。 MockMvc和WebTestClient之间的区别是什么?

  • 有人能给我解释一下map和flatMap之间的区别,以及什么是各自的好用例吗? “结果扁平化”是什么意思?它有什么好处?