noclassdeffounderror和classnotfoundexception之间的原因和区别是什么?

b4lqfgs4  于 2021-07-14  发布在  Java
关注(0)|答案(8)|浏览(348)

两者有什么区别 NoClassDefFoundError 以及 ClassNotFoundException ?
是什么导致他们被扔出去的?如何解决?
在修改现有代码以包含新的jar文件时,我经常会遇到这些问题。对于通过webstart分发的java应用程序,我在客户端和服务器端都找到了它们。
我遇到的可能原因:
不包括在 build.xml 对于代码的客户端
我们正在使用的新jar缺少运行时类路径
版本与以前的jar冲突
当我今天遇到这些问题时,我会采取循序渐进的方法来解决问题。我需要更多的清晰和理解。

bxgwgixi

bxgwgixi1#

与javaapi规范的区别如下。
为了 ClassNotFoundException :
当应用程序试图通过其字符串名称加载类时引发,使用:
这个 forName 类中的方法 Class .
这个 findSystemClass 类中的方法 ClassLoader .
这个 loadClass 类中的方法 ClassLoader .
但找不到具有指定名称的类的定义。
为了 NoClassDefFoundError :
如果java虚拟机或 ClassLoader 示例尝试加载类的定义(作为普通方法调用的一部分或使用新表达式创建新示例的一部分),但找不到该类的定义。
编译当前执行的类时,已存在搜索的类定义,但无法再找到该定义。
所以,看起来 NoClassDefFoundError 在成功编译源代码时发生,但在运行时 class 找不到文件。这可能是在jar文件的分发或生产过程中发生的事情,在这种情况下并不需要所有 class 包括文件。
至于 ClassNotFoundException ,它可能源于试图在运行时对类进行反射调用,但程序试图调用的类不存在。
两者的区别在于一个是 Error 另一个是一个 Exception . 与 NoClassDefFoundError 是一个 Error 它产生于java虚拟机在寻找它期望找到的类时遇到问题。在编译时工作的程序无法运行,因为 class 找不到文件,或者与编译时生成或遇到的文件不同。这是一个非常严重的错误,因为程序不能由jvm启动。
另一方面 ClassNotFoundException 是一个 Exception 因此,这在某种程度上是意料之中的,而且是可以恢复的。使用反射很容易出错(因为有些人认为事情可能不会按预期进行)。没有编译时检查来查看所有必需的类是否存在,因此查找所需类的任何问题都将在运行时出现。

igsr9ssn

igsr9ssn2#

当类加载器找不到报告的类时,将引发classnotfoundexception。这通常意味着类路径中缺少类。这也可能意味着所讨论的类正试图从另一个加载在父类加载器中的类中加载,因此子类加载器中的类不可见。在更复杂的环境(比如应用服务器)中工作时有时会出现这种情况(websphere因此类类加载器问题而臭名昭著)。
人们往往容易混淆 java.lang.NoClassDefFoundErrorjava.lang.ClassNotFoundException 但是有一个重要的区别。例如一个异常(一个真正的错误) java.lang.NoClassDefFoundError 是java.lang.error的子类

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

并不意味着activemqconnectionfactory类不在类路径中。事实恰恰相反。这意味着类加载器找到了类activemqconnectionfactory,但是在尝试加载该类时,它在读取类定义时遇到了错误。当所讨论的类具有静态块或成员,而这些静态块或成员使用的是类加载器找不到的类时,通常会发生这种情况。因此,要找到罪魁祸首,请查看相关类的源代码(本例中为activemqconnectionfactory),并使用静态块或静态成员查找代码。如果您没有访问源代码的权限,那么只需使用jad对其进行反编译。
在检查代码时,假设您发现一行如下所示的代码,请确保类someclass位于类路径中。

private static SomeClass foo = new SomeClass();

提示:要找出类属于哪个jar,可以使用网站jarfinder。这允许您使用通配符指定类名,并在jar数据库中搜索该类。jarhoo允许你做同样的事情,但它不再免费使用。
如果您想在本地路径中找到一个类所属的jar,可以使用jarscan(http://www.inetfeedback.com/jarscan/ ). 您只需指定要定位的类和根目录路径,以便在jars和zip文件中开始搜索该类。

yks3o0rb

yks3o0rb3#

NoClassDefFoundError 基本上是一个联动误差。它发生在您尝试示例化一个对象时(静态使用“new”),而在编译期间找不到它。 ClassNotFoundException 更一般,并且在尝试使用不存在的类时是运行时异常。例如,在函数中有一个参数接受一个接口,有人传入实现该接口的类,但您无权访问该类。它还包括动态类加载的情况,例如 loadClass() 或者 Class.forName() .

edqdpe6u

edqdpe6u4#

当代码运行“new y()”并且找不到y类时,会发生noclassdeffounderror(ncdfe)。
可能只是像其他注解所建议的那样,y从类装入器中丢失了,但可能是y类没有签名或签名无效,或者y是由代码看不到的其他类装入器装入的,甚至y依赖于z,而z由于上述任何原因都无法装入。
如果发生这种情况,jvm将记住加载x(ncdfe)的结果,并且每次您请求y时它都会抛出一个新的ncdfe,而不会告诉您原因:

class a {
  static class b {}
  public static void main(String args[]) {
    System.out.println("First attempt new b():");
    try {new b(); } catch(Throwable t) {t.printStackTrace();}
    System.out.println("\nSecond attempt new b():");
    try {new b(); } catch(Throwable t) {t.printStackTrace();}
  }
}

将此另存为a.java
代码只是尝试示例化一个新的“b”类两次,除此之外,它没有任何bug,也没有做任何事情。
使用编译代码 javac a.java ,然后通过调用 java -cp . a --它应该只打印出两行文本,并且应该运行良好,没有错误。
然后删除“a$b.class”文件(或者用垃圾填充它,或者在上面复制一个.class)来模拟丢失或损坏的类。下面是发生的情况:

First attempt new b():
java.lang.NoClassDefFoundError: a$b
    at a.main(a.java:5)
Caused by: java.lang.ClassNotFoundException: a$b
    at java.net.URLClassLoader$1.run(URLClassLoader.java:200)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:252)
    at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:320)
    ... 1 more

Second attempt new b():
java.lang.NoClassDefFoundError: a$b
    at a.main(a.java:7)

第一次调用会导致classnotfoundexception(当类加载器找不到类时抛出),必须将其 Package 在未检查的noclassdeffounderror中,因为有问题的代码( new b() )应该就行了。
第二次尝试当然也会失败,但是正如您所看到的, Package 的异常不再存在,因为类装入器似乎记住了失败的类装入器。你只看到ncdfe完全不知道到底发生了什么。
因此,如果您曾经看到一个没有根本原因的ncdfe,那么您需要查看是否可以追溯到第一次加载类时,以找到错误的原因。

olqngx59

olqngx595#

从http://www.javaroots.com/2013/02/classnotfoundexception-vs.html: ClassNotFoundException :当类加载器在类路径中找不到所需的类时发生。所以,基本上你应该检查你的类路径并在类路径中添加类。 NoClassDefFoundError :这更难调试并找到原因。当在编译时存在所需的类,但在运行时更改或删除这些类,或者类的静态初始化引发异常时,就会引发这种情况。这意味着要加载的类存在于类路径中,但该类所需的某个类被编译器删除或加载失败。所以你应该看到依赖于这个类的类。
例子:

public class Test1
{
}

public class Test 
{
   public static void main(String[] args)
   {
        Test1 = new Test1();    
   }

}

现在编译完这两个类之后,如果删除test1.class文件并运行test class,它将抛出

Exception in thread "main" java.lang.NoClassDefFoundError: Test
    at Test1.main(Test1.java:5)
Caused by: java.lang.ClassNotFoundException: Test
    at java.net.URLClassLoader$1.run(Unknown Source)
    at java.net.URLClassLoader$1.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(Unknown Source)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    ... 1 more
``` `ClassNotFoundException` :当应用程序试图通过其名称加载到类中,但找不到具有指定名称的类的定义时引发。 `NoClassDefFoundError` :如果java虚拟机尝试加载类的定义,但找不到该类的定义,则引发。
gj3fmq9x

gj3fmq9x6#

是什么原因让他们每一个和任何思想过程如何处理这些错误?
他们关系密切。一 ClassNotFoundException 当java按名称查找特定类而无法成功加载该类时引发。一 NoClassDefFoundError 当java查找链接到某个现有代码中的类时抛出,但由于某种原因(例如,错误的类路径、错误的java版本、错误的库版本)而找不到该类,这是完全致命的,因为它表明某些东西出了严重错误。
如果你有c的背景,cnfe就像是失败的 dlopen() / dlsym() 而ncdfe是链接器的问题;在第二种情况下,相关的类文件不应该在您试图使用它们的配置中实际编译。

xxb16uws

xxb16uws7#

示例#1:

class A{
 void met(){
   Class.forName("com.example.Class1");
 }
}

如果 com/example/Class1 在任何类路径中都不存在,然后它抛出 ClassNotFoundException .
示例2:

Class B{
  void met(){
   com.example.Class2 c = new com.example.Class2();
 }
}

如果 com/example/Class2 在编译b时存在,但在执行时找不到,然后抛出 NoClassDefFoundError .
两者都是运行时异常。

mrphzbgm

mrphzbgm8#

当试图通过字符串引用类来加载该类时,将引发classnotfoundexception。例如,class.forname()中的参数是一个字符串,这可能导致传递给类加载器的二进制名称无效。
当遇到可能无效的二进制名称时抛出classnotfoundexception;例如,如果类名具有“/”字符,则您将得到classnotfoundexception。当直接引用的类在类路径上不可用时,也会抛出它。
另一方面,抛出noclassdeffounderror
当类的实际物理表示形式.class文件不可用时,
或者班上的蜜蜂

相关问题