--- old/src/hotspot/share/oops/instanceKlass.cpp 2018-07-06 15:39:25.078205630 +0000 +++ new/src/hotspot/share/oops/instanceKlass.cpp 2018-07-06 15:39:24.967204841 +0000 @@ -934,17 +934,19 @@ if (is_in_error_state()) { DTRACE_CLASSINIT_PROBE_WAIT(erroneous, -1, wait); ResourceMark rm(THREAD); - const char* desc = "Could not initialize class "; - 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); + // 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(); + THROW_MSG(vmSymbols::java_lang_NoClassDefFoundError(), className); } // Step 6 @@ -974,6 +976,9 @@ 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; @@ -1019,6 +1024,20 @@ 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 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 @@ -1026,14 +1045,7 @@ 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); - } + THROW_OOP(e()); } DTRACE_CLASSINIT_PROBE_WAIT(end, -1, wait); }