[ACCEPTED]-Why NoClassDefFoundError caused by static field initialization failure?-noclassdeffounderror
The answer to such questions is usually 37 buried somewhere in the specs... (§12.4.2)
What happens 36 when classes are initialized:
Steps 1-4 are 35 somewhat unrelated to this question. Step 34 5 here is what triggers the exception:
5
. If the Class object is in an erroneous state, then 33 initialization is not possible. Release 32 the lock on the Class object and throw a NoClassDefFoundError.
6-8 continue 31 the initialization, 8 executes the initializers, and 30 what usually happens is in step 9:
9
. If the 29 execution of the initializers completes 28 normally, then lock this Class object, label 27 it fully initialized, notify all waiting 26 threads, release the lock, and complete 25 this procedure normally.
But we got an error 24 in the initializer so:
10
. Otherwise, the initializers must have completed abruptly by throwing some exception E. If the class of 23 E is not Error or one of its subclasses, then 22 create a new instance of the class ExceptionInInitializerError, with E as the argument, and use this object in place of E in the 21 following step. But if a new instance of 20 ExceptionInInitializerError cannot be created 19 because an OutOfMemoryError occurs, then 18 instead use an OutOfMemoryError object in 17 place of E in the following step.
Yep, we 16 see an ExceptionInInitializerError
b/c of the null pointer exception.
11
. Lock 15 the Class object, label it erroneous, notify all waiting threads, release 14 the lock, and complete this procedure abruptly 13 with reason E or its replacement as determined 12 in the previous step. (Due to a flaw in 11 some early implementations, a exception 10 during class initialization was ignored, rather 9 than causing an ExceptionInInitializerError 8 as described here.)
And then the class is 7 marked erroneous which is why we get the 6 exception from step 5 the second time.
The 5 surprising part is the third printout which 4 shows that
TestClass.class
inMainClass
actually holds a reference 3 to a physicalClass
object.
Probably because TestClass
still 2 exists, it's just marked erroneous. It has 1 been already loaded and verified.
Yes, that's usually why NoClassDefFoundError
is raised. It's 9 evilly named, that's all. It should've been named 8 as "class init failed exception" or something.
Becuase 7 of the misleading name, java programmers 6 who got this error wasted hundreds of man 5 years trying to figure out why the class 4 cannot be found.
Whenever you see this exception, you 3 should check the log upwards, and try to 2 find out the root cause when the class failed 1 to init.
When I access such a static field, a NoClassDefFoundError 14 will raised. it seems the VM treat the Class 13 is not complete.
That is correct ...
But when 12 I access the Class, it still available
Yes.
The 11 class loader has not tried to remove the 10 broken class because:
- it would be difficult to do,
- it would be extremely difficult to do safely,
- it would leave the JVM in a state where an application could easily waste lots of time repeatedly loading and reloading broken code, and
- the specs say (or at least imply) that it shouldn't; see other answers for details.
To get into a state 9 where this inconsistency is visible, your 8 application has to catch ClassDefNotFoundError
(or a superclass) and 7 attempted to recover from it. It is a well 6 documented fact that Error
exceptions are generally 5 not recoverable; i.e. if you attempt to 4 recover, the JVM may end up in an inconsistent 3 state. That is what has happened here ... with 2 respect to the classes that were being loaded 1 / initialized.
More Related questions
We use cookies to improve the performance of the site. By staying on our site, you agree to the terms of use of cookies.