JVM规范在提及NoClassDefFoundError

来源:互联网 发布:string数组中删除元素 编辑:程序博客网 时间:2024/04/29 11:13
 

JVM规范在提及NoClassDefFoundError说到了2处:

(1)     

 

q 如果C的Class对象显示它处于一个错误的状态,就不再初始化了。释放LC并抛出NoClassDefFoundError异常。

意思是说C初始化失败了,那么第二次就直接抛出这个异常NoClassDefFoundError

如Truman提供的例子(我稍加改编如下):

 

       for(int i = 0; i <2 ; i ++){

           try {

              TimeUnit.SECONDS.sleep(3);

           } catch (InterruptedException e1) {

              e1.printStackTrace();

           }

           try {

              Caller.test();

           } catch (Throwable e) {

              System.out.println("_____________________");

              e.printStackTrace();

           }

 

 

java.lang.ExceptionInInitializerError-第一次初始化失败

    at com.cisco.webex.Test.main(Test.java:14)

Caused by: java.lang.RuntimeException: throw exception in constructor.

    at com.cisco.webex.PramterA.<init>(PramterA.java:6)

    at com.cisco.webex.Caller.<clinit>(Caller.java:12)

    ... 1 more

_____________________第二次初始化直接报NoClassDefFoundError

java.lang.NoClassDefFoundError: Could not initialize class com.cisco.webex.Caller

    at com.cisco.webex.Test.main(Test.java:14)

 

 

(2)  

如果Java虚拟机曾经试图在D(调用者)的验证(§5.4.1)或解析(§5.4.3)阶段、但又还没有进行初始化(§5.5)时加载C类,当用于加载C的初始类加载器抛出ClassNotFoundException实例时,Java虚拟机在D中必须抛出NoClassDefFoundError异常,它的cause字段中就保存了那个ClassNotFoundException异常实例。

 

例如:

public class Invoker {

 

    public static final Object fileService = new ExternalGek4();

 

    public Invoker() {

 

    }

 

}

假设我在编译后,运行前删除ExternalGek4,然后运行new Invoker(),这个时候会抛出NoClassDefFoundError, 当然cause是(ClassNotFoundException)。

 

这个和JAVADOC里面说的很匹配:

* Thrown if the Java Virtual Machine or a <code>ClassLoader</code> instance

 * tries to load in the definition of a class (as part of a normal method call

 * or as part of creating a new instance using the <code>new</code> expression)

 * and no definition of the class could be found.

 * <p>

 * The searched-for class definition existed when the currently

 * executing class was compiled, but the definition can no longer be

 * found.

编译在,运行时不在了。

 

 

总结:

 

NoClassDefFoundError 这种错误应该有2个原因可能导致:

(1)   第一次初始化对象失败,第二次时报错。

(2)   类真的找不到

特征前者是第一次初始化中有错, 后者是含有 class not found(CLASS PATH等问题)的CAUSE

 

 那么根绝相应的LOG就可以简单判断是那种错误。然后有针对性的处理。

 

  Ps 与CLASSNOTFOUND的区别:

CLASSNOTFOUND有可能包装成NoClassDefFoundError

NoClassDefFoundError可以不由classnotfoundexception引起。