JDK-8051847 : Subsequent NoClassDefFoundError.cause not set to ExceptionInInitializerError
  • Type: Enhancement
  • Component: core-libs
  • Sub-Component: java.lang
  • Affected Version: 7,8
  • Priority: P4
  • Status: Open
  • Resolution: Unresolved
  • OS: linux
  • CPU: x86
  • Submitted: 2012-09-20
  • Updated: 2018-03-16
Description
A DESCRIPTION OF THE REQUEST :
When a static initializer fails with an exception, an ExceptionInInitializerError with cause is thrown to the code initially trying to use the class���good.

But after that initial ExceptionInInitializerError, subsequent attempts to use the class throw a NoClassDefFoundError with no cause, offering no information about the original exception.

JUSTIFICATION :
In a large software system it is easy for the initial ExceptionInInitializerError to be lost somehow. Perhaps it was printed to a log, but this was rotated out of easy view���or deleted altogether. Perhaps some code caught LinkageError but ���swallowed��� it or logged it only at a verbose level; this is not so uncommon when using a dependency injection framework, a module system resilient to binary compatibility issues, and so on.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Would prefer to have the ExceptionInInitializerError be retained and used as the cause for a subsequent NoClassDefFoundError:

Exception in thread "main" java.lang.NoClassDefFoundError: Could not initialize class Demo$CrucialComponent
	at Demo.main(Demo.java:6)
Caused by: java.lang.ExceptionInInitializerError
	at Demo.main(Demo.java:4)
Caused by: java.lang.IllegalStateException: Too many blattlies!
	at Demo$CrucialComponent.<clinit>(Demo.java:11)
	... 1 more
ACTUAL -
In JDK 7u7:

Exception in thread "main" java.lang.NoClassDefFoundError: Could not initialize class Demo$CrucialComponent
	at Demo.main(Demo.java:6)

---------- BEGIN SOURCE ----------
public class Demo {
    public static void main(String... args) {
        try {
            CrucialComponent.run();
        } catch (LinkageError x) {}
        CrucialComponent.run();
    }
    static class CrucialComponent {
        static {
            if (Demo.class != null) {
                throw new IllegalStateException("Too many blattlies!");
            }
        }
        static void run() {}
    }
}
---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
None known.

Comments
Kohsuke Kawaguchi wrote a java agent to find all those swallowed ExceptionInInitializerErrors http://kohsuke.org/2015/01/28/potd-exceptionininitializererror-logger/ http://eiie-logger.kohsuke.org/ (added here as requested by Jesse Glick)
10-03-2018

http://stackoverflow.com/questions/6352215/java-why-java-lang-noclassdeffounderror-caused-by-static-field-initializ-failur
10-03-2018

I think this is a dup of JDK-8048190 which hotspot team closed WNF. (and core libraries team probably can't implement it without hotspot team's help)
09-03-2018