< prev index next >

src/hotspot/share/oops/instanceKlass.cpp

Print this page

        

@@ -932,21 +932,23 @@
 
     // Step 5
     if (is_in_error_state()) {
       DTRACE_CLASSINIT_PROBE_WAIT(erroneous, -1, wait);
       ResourceMark rm(THREAD);
-      const char* desc = "Could not initialize class ";
+      // Delegate throwing of NoClassDefFoundError to java handler
+      class_loader_data()->throw_reinit_exception(java_mirror_handle(), THREAD);
+      if (HAS_PENDING_EXCEPTION) {
+        Handle e(THREAD, PENDING_EXCEPTION);
+        CLEAR_PENDING_EXCEPTION;
+        if (e->is_a(SystemDictionary::NoClassDefFoundError_klass())) {
+          // java handler has thrown correct type of exception -> rethrow it
+          THROW_OOP(e());
+        }
+      }
+      // misbehaving/incapable java handler (throwing OOME or not at all) -> fallback
       const char* className = external_name();
-      size_t msglen = strlen(desc) + strlen(className) + 1;
-      char* message = NEW_RESOURCE_ARRAY(char, msglen);
-      if (NULL == message) {
-        // Out of memory: can't create detailed error message
           THROW_MSG(vmSymbols::java_lang_NoClassDefFoundError(), className);
-      } else {
-        jio_snprintf(message, msglen, "%s%s", desc, className);
-          THROW_MSG(vmSymbols::java_lang_NoClassDefFoundError(), message);
-      }
     }
 
     // Step 6
     set_init_state(being_initialized);
     set_init_thread(self);

@@ -972,10 +974,13 @@
     if (HAS_PENDING_EXCEPTION) {
       Handle e(THREAD, PENDING_EXCEPTION);
       CLEAR_PENDING_EXCEPTION;
       {
         EXCEPTION_MARK;
+        // Record the exception thrown from super class/interface initialization so that
+        // it can be chained into potential later NoClassDefFoundErrors.
+        class_loader_data()->record_init_exception(java_mirror_handle(), e, THREAD);
         // Locks object, set state, and notify all waiting threads
         set_initialization_state_and_notify(initialization_error, THREAD);
         CLEAR_PENDING_EXCEPTION;
       }
       DTRACE_CLASSINIT_PROBE_WAIT(super__failed, -1, wait);

@@ -1017,25 +1022,32 @@
     // JVMTI has already reported the pending exception
     // JVMTI internal flag reset is needed in order to report ExceptionInInitializerError
     JvmtiExport::clear_detected_exception((JavaThread*)THREAD);
     {
       EXCEPTION_MARK;
+      if (!e->is_a(SystemDictionary::Error_klass())) {
+        // Wrap anything but errors into ExceptionInInitializerError.
+        JavaCallArguments args(e);
+        Handle h_loader(THREAD, NULL);
+        Handle h_prot(THREAD, NULL);
+        e = Exceptions::new_exception(THREAD,
+                                      vmSymbols::java_lang_ExceptionInInitializerError(),
+                                      vmSymbols::throwable_void_signature(),
+                                      &args, h_loader, h_prot);
+      }
+      // Record the exception that originally caused <clinit> to fail so
+      // it can be chained into potential later NoClassDefFoundErrors.
+      class_loader_data()->record_init_exception(java_mirror_handle(), e, THREAD);
+      // Locks object, set state, and notify all waiting threads
       set_initialization_state_and_notify(initialization_error, THREAD);
       CLEAR_PENDING_EXCEPTION;   // ignore any exception thrown, class initialization error is thrown below
       // JVMTI has already reported the pending exception
       // JVMTI internal flag reset is needed in order to report ExceptionInInitializerError
       JvmtiExport::clear_detected_exception((JavaThread*)THREAD);
     }
     DTRACE_CLASSINIT_PROBE_WAIT(error, -1, wait);
-    if (e->is_a(SystemDictionary::Error_klass())) {
       THROW_OOP(e());
-    } else {
-      JavaCallArguments args(e);
-      THROW_ARG(vmSymbols::java_lang_ExceptionInInitializerError(),
-                vmSymbols::throwable_void_signature(),
-                &args);
-    }
   }
   DTRACE_CLASSINIT_PROBE_WAIT(end, -1, wait);
 }
 
 
< prev index next >