Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8048190

NoClassDefFoundError omits original ExceptionInInitializerError

    Details

    • Type: Enhancement
    • Status: Closed
    • Priority: P4
    • Resolution: Won't Fix
    • Affects Version/s: 7u60
    • Fix Version/s: 9
    • Component/s: hotspot
    • Subcomponent:
    • CPU:
      x86_64
    • OS:
      linux

      Description

      A DESCRIPTION OF THE REQUEST :
      It is common for various subtle bugs in software, or configuration issues on certain machines, to cause a static initializer to fail, which produces a ExceptionInInitializerError. If this error is caught and logged to appropriate channels then the application developer or support person can easily track down the problem, and normally that is what happens.

      However on occasion the ExceptionInInitializerError is “swallowed” due to buggy error handling code, which might be difficult or impossible to locate in a large modular application. If this happens, subsequent references to the problematic class throw a NoClassDefFoundError, yet omit any information about *why* the class could not be loaded; this information is apparently unreconstructible.

      Related to JDK-4470034 and JDK-6747450 yet distinct from these.

      JUSTIFICATION :
      Crucial for field diagnosis of complex errors. I have personally encountered this problem on a number of occasions and spent a lot of time tracking down the root cause. (In the current case I am unable to find the original error at all, and the problem has disappeared after a JVM restart so cannot be reproduced.)

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      When an ExceptionInInitializerError is thrown, this error ought to be saved in class metadata by the JVM, and used as a NoClassDefFoundError.cause if any subsequent attempts to load the class are made.
      ACTUAL -
      There is no cause in the NoClassDefFoundError, and the detail message gives little information beyond the name of the class and the implication that an ExceptionInInitializerError was involved.

      ---------- BEGIN SOURCE ----------
      public class Demo {
          public static void main(String[] args) throws Exception {
              try {
                  new X();
              } catch (LinkageError x) {
                  // ignore
              }
              new X();
          }
          public static final class X {
              static {
                  if (X.class != null) {
                      throw new IllegalStateException("Oops!");
                  }
              }
          }
      }

      on JDK 7u60 or 8u0 produces simply:

      Exception in thread "main" java.lang.NoClassDefFoundError: Could not initialize class Demo$X
      at Demo.main(Demo.java:8)
      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      None known, other than somehow tracking down the original ExceptionInInitializerError from some earlier log if it was ever recorded at all.

        Activity

        Hide
        dholmes David Holmes added a comment -
        The only semantics issue I have with this request is whether it is appropriate to set as a "cause", an exception that was thrown in a different thread and which has a stack trace unrelated to the current thread. That might cause even more confusion to the user not realizing the original exception was in another thread! (We will get bug reports about exceptions being thrown from code that was never executed!)

        Perhaps we should simply update the message:

        java.lang.NoClassDefFoundError: Class Demo$X is in erroneous state due to a failed static initialization attempt
        Show
        dholmes David Holmes added a comment - The only semantics issue I have with this request is whether it is appropriate to set as a "cause", an exception that was thrown in a different thread and which has a stack trace unrelated to the current thread. That might cause even more confusion to the user not realizing the original exception was in another thread! (We will get bug reports about exceptions being thrown from code that was never executed!) Perhaps we should simply update the message: java.lang.NoClassDefFoundError: Class Demo$X is in erroneous state due to a failed static initialization attempt
        Hide
        coleenp Coleen Phillimore added a comment -
        Where we produce this message "Could not initialize class Demo$X" could be for any sort of initialization error so the only way to really get this correct is to save the pending exception (if that works). With the option -XX:+TraceExceptions now available to product mode, I think this RFE is no longer needed. Closing as WNF.
        Show
        coleenp Coleen Phillimore added a comment - Where we produce this message "Could not initialize class Demo$X" could be for any sort of initialization error so the only way to really get this correct is to save the pending exception (if that works). With the option -XX:+TraceExceptions now available to product mode, I think this RFE is no longer needed. Closing as WNF.
        Hide
        coleenp Coleen Phillimore added a comment -
        Use -XX:+TraceExceptions.
        Show
        coleenp Coleen Phillimore added a comment - Use -XX:+TraceExceptions.

          People

          • Assignee:
            coleenp Coleen Phillimore
            Reporter:
            webbuggrp Webbug Group
          • Votes:
            0 Vote for this issue
            Watchers:
            5 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: