--- old/src/hotspot/share/classfile/classFileParser.cpp 2020-03-08 19:02:53.589560716 -0400 +++ new/src/hotspot/share/classfile/classFileParser.cpp 2020-03-08 19:02:52.436547939 -0400 @@ -5678,7 +5678,7 @@ // can only set dynamic nest-host after static nest information is set if (cl_inst_info.dynamic_nest_host() != NULL) { - ik->set_nest_host(cl_inst_info.dynamic_nest_host(), CHECK); + ik->set_nest_host(cl_inst_info.dynamic_nest_host(), THREAD); } // note that is not safe to use the fields in the parser from this point on --- old/src/hotspot/share/interpreter/linkResolver.cpp 2020-03-08 19:02:59.253623481 -0400 +++ new/src/hotspot/share/interpreter/linkResolver.cpp 2020-03-08 19:02:58.099610693 -0400 @@ -579,24 +579,51 @@ sel_klass, flags, true, false, CHECK); - // Any existing exceptions that may have been thrown, for example LinkageErrors - // from nest-host resolution, have been allowed to propagate. + // Any existing exceptions that may have been thrown + // have been allowed to propagate. if (!can_access) { ResourceMark rm(THREAD); + stringStream ss; bool same_module = (sel_klass->module() == ref_klass->module()); - Exceptions::fthrow( - THREAD_AND_LOCATION, - vmSymbols::java_lang_IllegalAccessError(), - "class %s tried to access %s%s%smethod '%s' (%s%s%s)", - ref_klass->external_name(), - sel_method->is_abstract() ? "abstract " : "", - sel_method->is_protected() ? "protected " : "", - sel_method->is_private() ? "private " : "", - sel_method->external_name(), - (same_module) ? ref_klass->joint_in_module_of_loader(sel_klass) : ref_klass->class_in_module_of_loader(), - (same_module) ? "" : "; ", - (same_module) ? "" : sel_klass->class_in_module_of_loader() - ); + ss.print("class %s tried to access %s%s%smethod '%s' (%s%s%s)", + ref_klass->external_name(), + sel_method->is_abstract() ? "abstract " : "", + sel_method->is_protected() ? "protected " : "", + sel_method->is_private() ? "private " : "", + sel_method->external_name(), + (same_module) ? ref_klass->joint_in_module_of_loader(sel_klass) : ref_klass->class_in_module_of_loader(), + (same_module) ? "" : "; ", + (same_module) ? "" : sel_klass->class_in_module_of_loader() + ); + + // For private access check if there was a problem with nest host + // resolution, and if so report that as part of the message. + if (sel_method->is_private()) { + assert(ref_klass->is_instance_klass(), "must be"); + assert(sel_klass->is_instance_klass(), "must be"); + InstanceKlass* ref_ik = InstanceKlass::cast(ref_klass); + InstanceKlass* sel_ik = InstanceKlass::cast(sel_klass); + const char* nest_host_error_1 = ref_ik->nest_host_resolution_error(); + const char* nest_host_error_2 = sel_ik->nest_host_resolution_error(); + if (nest_host_error_1 != NULL || nest_host_error_2 != NULL) { + ss.print(", ("); + if (nest_host_error_1 != NULL) { + ss.print("%s", nest_host_error_1); + if (nest_host_error_2 != NULL) { + ss.print(", %s", nest_host_error_2); + } + } else if (nest_host_error_2 != NULL) { + ss.print("%s", nest_host_error_2); + } + ss.print(")"); + } + } + + Exceptions::fthrow(THREAD_AND_LOCATION, + vmSymbols::java_lang_IllegalAccessError(), + "%s", + ss.as_string() + ); return; } } @@ -915,19 +942,44 @@ if (!can_access) { bool same_module = (sel_klass->module() == ref_klass->module()); ResourceMark rm(THREAD); - Exceptions::fthrow( - THREAD_AND_LOCATION, - vmSymbols::java_lang_IllegalAccessError(), - "class %s tried to access %s%sfield %s.%s (%s%s%s)", - ref_klass->external_name(), - fd.is_protected() ? "protected " : "", - fd.is_private() ? "private " : "", - sel_klass->external_name(), - fd.name()->as_C_string(), - (same_module) ? ref_klass->joint_in_module_of_loader(sel_klass) : ref_klass->class_in_module_of_loader(), - (same_module) ? "" : "; ", - (same_module) ? "" : sel_klass->class_in_module_of_loader() - ); + stringStream ss; + ss.print("class %s tried to access %s%sfield %s.%s (%s%s%s)", + ref_klass->external_name(), + fd.is_protected() ? "protected " : "", + fd.is_private() ? "private " : "", + sel_klass->external_name(), + fd.name()->as_C_string(), + (same_module) ? ref_klass->joint_in_module_of_loader(sel_klass) : ref_klass->class_in_module_of_loader(), + (same_module) ? "" : "; ", + (same_module) ? "" : sel_klass->class_in_module_of_loader() + ); + // For private access check if there was a problem with nest host + // resolution, and if so report that as part of the message. + if (fd.is_private()) { + assert(ref_klass->is_instance_klass(), "must be"); + assert(sel_klass->is_instance_klass(), "must be"); + InstanceKlass* ref_ik = InstanceKlass::cast(ref_klass); + InstanceKlass* sel_ik = InstanceKlass::cast(sel_klass); + const char* nest_host_error_1 = ref_ik->nest_host_resolution_error(); + const char* nest_host_error_2 = sel_ik->nest_host_resolution_error(); + if (nest_host_error_1 != NULL || nest_host_error_2 != NULL) { + ss.print(", ("); + if (nest_host_error_1 != NULL) { + ss.print("%s", nest_host_error_1); + if (nest_host_error_2 != NULL) { + ss.print(", %s", nest_host_error_2); + } + } else if (nest_host_error_2 != NULL) { + ss.print("%s", nest_host_error_2); + } + ss.print(")"); + } + } + Exceptions::fthrow(THREAD_AND_LOCATION, + vmSymbols::java_lang_IllegalAccessError(), + "%s", + ss.as_string() + ); return; } } --- old/src/hotspot/share/oops/instanceKlass.cpp 2020-03-08 19:03:03.919675187 -0400 +++ new/src/hotspot/share/oops/instanceKlass.cpp 2020-03-08 19:03:02.659661225 -0400 @@ -153,7 +153,9 @@ return false; } -// called to verify that k is a member of this nest +// private: called to verify that k is a static member of this nest. +// We know that k is an instance class in the same package and hence the +// same classloader. bool InstanceKlass::has_nest_member(InstanceKlass* k, TRAPS) const { assert(!is_hidden(), "unexpected hidden class"); if (_nest_members == NULL || _nest_members == Universe::the_empty_short_array()) { @@ -176,7 +178,9 @@ for (int i = 0; i < _nest_members->length(); i++) { int cp_index = _nest_members->at(i); if (_constants->tag_at(cp_index).is_klass()) { - Klass* k2 = _constants->klass_at(cp_index, CHECK_false); + Klass* k2 = _constants->klass_at(cp_index, THREAD); + assert(!HAS_PENDING_EXCEPTION || PENDING_EXCEPTION->is_a(SystemDictionary::VirtualMachineError_klass()), + "Exceptions should not be possible here"); if (k2 == k) { log_trace(class, nestmates)("- class is listed at nest_members[%d] => cp[%d]", i, cp_index); return true; @@ -187,15 +191,14 @@ if (name == k->name()) { log_trace(class, nestmates)("- Found it at nest_members[%d] => cp[%d]", i, cp_index); - // Names match so check actual klass - this may trigger class loading if - // it doesn't match (though that should be impossible). But to be safe we - // have to check for a compiler thread executing here. - if (!THREAD->can_call_java() && !_constants->tag_at(cp_index).is_klass()) { - log_trace(class, nestmates)("- validation required resolution in an unsuitable thread"); - return false; - } - - Klass* k2 = _constants->klass_at(cp_index, CHECK_false); + // Names match so check actual klass. This may trigger class loading if + // it doesn't match though that should be impossible as it means one classloader + // has defined two different classes with the same name! A compiler thread won't be + // able to perform that loading but we can't exclude the compiler threads from + // executing this logic. But it should actually be impossible to trigger loading here. + Klass* k2 = _constants->klass_at(cp_index, THREAD); + assert(!HAS_PENDING_EXCEPTION || PENDING_EXCEPTION->is_a(SystemDictionary::VirtualMachineError_klass()), + "Exceptions should not be possible here"); if (k2 == k) { log_trace(class, nestmates)("- class is listed as a nest member"); return true; @@ -213,148 +216,133 @@ return false; } -InstanceKlass* InstanceKlass::runtime_nest_host(TRAPS) { - // TODO: nest_host returns NULL if validation fails. Need to follow up - // the specification when to evaluate the runtime nest host. Right now - // it's only determined when a dynamic nestmate is added. - InstanceKlass* nest_host_k = nest_host(NULL, CHECK_NULL); - if (nest_host_k == NULL) { - assert(_nest_host == NULL, "should fail to validate NestNost"); - // drop the static nest information; set dynamic nest to this class - if (log_is_enabled(Trace, class, nestmates)) { - ResourceMark rm(THREAD); - log_trace(class, nestmates)("Fail to validate static nest host of %s: setting nest-host to self", - this->external_name()); - } - _nest_host = nest_host_k = this; - } - return nest_host_k; -} - // Return nest-host class, resolving, validating and saving it if needed. -// In cases where this is called from a thread that can not do classloading +// In cases where this is called from a thread that cannot do classloading // (such as a native JIT thread) then we simply return NULL, which in turn // causes the access check to return false. Such code will retry the access -// from a more suitable environment later. -InstanceKlass* InstanceKlass::nest_host(Symbol* validationException, TRAPS) { +// from a more suitable environment later. Otherwise the _nest_host is always +// set once this method returns. +// Any errors from nest-host resolution must be preserved so they can be queried +// from higher-level access checking code, and reported as part of access checking +// exceptions. +// VirtualMachineErrors are propagated with a NULL return. +InstanceKlass* InstanceKlass::nest_host(TRAPS) { InstanceKlass* nest_host_k = _nest_host; - if (nest_host_k == NULL) { - // need to resolve and save our nest-host class. This could be attempted - // concurrently but as the result is idempotent and we don't use the class - // then we do not need any synchronization beyond what is implicitly used - // during class loading. - if (_nest_host_index != 0) { // we have a real nest_host - // Before trying to resolve check if we're in a suitable context - if (!THREAD->can_call_java() && !_constants->tag_at(_nest_host_index).is_klass()) { - if (log_is_enabled(Trace, class, nestmates)) { - ResourceMark rm(THREAD); - log_trace(class, nestmates)("Rejected resolution of nest-host of %s in unsuitable thread", - this->external_name()); - } - return NULL; - } + if (nest_host_k != NULL) { + return nest_host_k; + } - if (log_is_enabled(Trace, class, nestmates)) { + const bool doLog = log_is_enabled(Trace, class, nestmates); + + // need to resolve and save our nest-host class. This could be attempted + // concurrently but as the result is idempotent and we don't use the class + // then we do not need any synchronization beyond what is implicitly used + // during class loading. + if (_nest_host_index != 0) { // we have a real nest_host + // Before trying to resolve check if we're in a suitable context + if (!THREAD->can_call_java() && !_constants->tag_at(_nest_host_index).is_klass()) { + if (doLog) { ResourceMark rm(THREAD); - log_trace(class, nestmates)("Resolving nest-host of %s using cp entry for %s", - this->external_name(), - _constants->klass_name_at(_nest_host_index)->as_C_string()); + log_trace(class, nestmates)("Rejected resolution of nest-host of %s in unsuitable thread", + this->external_name()); } + return NULL; // sentinel to say "try again from a different context" + } - Klass* k = _constants->klass_at(_nest_host_index, THREAD); - if (HAS_PENDING_EXCEPTION) { - Handle exc_h = Handle(THREAD, PENDING_EXCEPTION); - if (validationException == NULL && exc_h->is_a(SystemDictionary::LinkageError_klass())) { - // clear exception if fails to resolve the nest host class - CLEAR_PENDING_EXCEPTION; - } - // throw a new NCDFE with the original as its cause, and a clear msg - if (exc_h->is_a(SystemDictionary::NoClassDefFoundError_klass()) && validationException != NULL) { - // throw a new NCDFE with the original as its cause, and a clear msg - ResourceMark rm(THREAD); - char buf[200]; - CLEAR_PENDING_EXCEPTION; - jio_snprintf(buf, sizeof(buf), - "Unable to load nest-host class (%s) of %s", - _constants->klass_name_at(_nest_host_index)->as_C_string(), - this->external_name()); - log_trace(class, nestmates)("%s - NoClassDefFoundError", buf); - THROW_MSG_CAUSE_NULL(vmSymbols::java_lang_NoClassDefFoundError(), buf, exc_h); - } - // All other exceptions pass through (OOME, StackOverflowError, LinkageErrors etc). - return NULL; - } + if (doLog) { + ResourceMark rm(THREAD); + log_trace(class, nestmates)("Resolving nest-host of %s using cp entry for %s", + this->external_name(), + _constants->klass_name_at(_nest_host_index)->as_C_string()); + } + Klass* k = _constants->klass_at(_nest_host_index, THREAD); + if (HAS_PENDING_EXCEPTION) { + if (PENDING_EXCEPTION->is_a(SystemDictionary::VirtualMachineError_klass())) { + return NULL; // propagate VMEs + } + ResourceMark rm(THREAD); + stringStream ss; + char* target_host_class = _constants->klass_name_at(_nest_host_index)->as_C_string(); + ss.print("Nest host resolution of %s with host %s failed: ", + this->external_name(), target_host_class); + java_lang_Throwable::print(PENDING_EXCEPTION, &ss); + _nest_host_res_error = ss.as_string(true /* on C-heap */); + CLEAR_PENDING_EXCEPTION; + if (doLog) { + log_trace(class, nestmates)("%s", _nest_host_res_error); + } + } else { // A valid nest-host is an instance class in the current package that lists this - // class as a nest member. If any of these conditions are not met we post the - // requested exception type (if any) and return NULL - + // class as a nest member. If any of these conditions are not met the class is + // its own nest-host. const char* error = NULL; // JVMS 5.4.4 indicates package check comes first if (is_same_class_package(k)) { - // Now check actual membership. We can't be a member if our "host" is // not an instance class. if (k->is_instance_klass()) { nest_host_k = InstanceKlass::cast(k); - - bool is_member = nest_host_k->has_nest_member(this, CHECK_NULL); - if (is_member) { - // save resolved nest-host value - _nest_host = nest_host_k; - - if (log_is_enabled(Trace, class, nestmates)) { - ResourceMark rm(THREAD); - log_trace(class, nestmates)("Resolved nest-host of %s to %s", - this->external_name(), k->external_name()); + bool is_member = nest_host_k->has_nest_member(this, THREAD); + // exception is rare, perhaps impossible + if (!HAS_PENDING_EXCEPTION) { + if (is_member) { + _nest_host = nest_host_k; // save resolved nest-host value + if (doLog) { + ResourceMark rm(THREAD); + log_trace(class, nestmates)("Resolved nest-host of %s to %s", + this->external_name(), k->external_name()); + } + return nest_host_k; + } else { + error = "current type is not listed as a nest member"; + } + } else { + if (PENDING_EXCEPTION->is_a(SystemDictionary::VirtualMachineError_klass())) { + return NULL; // propagate VMEs } - return nest_host_k; + stringStream ss; + ss.print("exception on member check: "); + java_lang_Throwable::print(PENDING_EXCEPTION, &ss); + error = ss.as_string(); } + } else { + error = "host is not an instance class"; } - error = "current type is not listed as a nest member"; } else { error = "types are in different packages"; } - if (log_is_enabled(Trace, class, nestmates)) { + // something went wrong, so record what and log it + { ResourceMark rm(THREAD); - log_trace(class, nestmates) - ("Type %s (loader: %s) is not a nest member of " - "resolved type %s (loader: %s): %s", - this->external_name(), - this->class_loader_data()->loader_name_and_id(), - k->external_name(), - k->class_loader_data()->loader_name_and_id(), - error); - } + stringStream ss; + ss.print("Type %s (loader: %s) is not a nest member of type %s (loader: %s): %s", + this->external_name(), + this->class_loader_data()->loader_name_and_id(), + k->external_name(), + k->class_loader_data()->loader_name_and_id(), + error); + _nest_host_res_error = ss.as_string(true /* on C-heap */); - if (validationException != NULL && THREAD->can_call_java()) { - ResourceMark rm(THREAD); - Exceptions::fthrow(THREAD_AND_LOCATION, - validationException, - "Type %s (loader: %s) is not a nest member of %s (loader: %s): %s", - this->external_name(), - this->class_loader_data()->loader_name_and_id(), - k->external_name(), - k->class_loader_data()->loader_name_and_id(), - error - ); - } - return NULL; - } else { - if (log_is_enabled(Trace, class, nestmates)) { - ResourceMark rm(THREAD); - log_trace(class, nestmates)("Type %s is not part of a nest: setting nest-host to self", - this->external_name()); + if (doLog) { + log_trace(class, nestmates)("%s", _nest_host_res_error); + } } - // save resolved nest-host value - return (_nest_host = this); + } + } else { + if (doLog) { + ResourceMark rm(THREAD); + log_trace(class, nestmates)("Type %s is not part of a nest: setting nest-host to self", + this->external_name()); } } - return nest_host_k; -} + // Either not in an explicit nest, or else an error occurred, so + // the nest-host is set to `this`. + return (_nest_host = this); +} // Dynamic nest member support: set this class's nest host to the given class. // This occurs as part of the class definition, as soon as the instanceKlass @@ -369,6 +357,8 @@ assert(is_hidden(), "must be a hidden class"); assert(host != NULL, "NULL nest host specified"); assert(_nest_host == NULL, "current class has resolved nest-host"); + assert(_nest_host_res_error == NULL, "unexpected nest host resolution error exists: %s", + _nest_host_res_error); assert((host->_nest_host == NULL && host->_nest_host_index == 0) || (host->_nest_host == host), "proposed host is not a valid nest-host"); // Can't assert this as package is not set yet: @@ -376,16 +366,17 @@ if (log_is_enabled(Trace, class, nestmates)) { ResourceMark rm(THREAD); + const char* msg = ""; // a hidden class does not expect a statically defined nest-host if (_nest_host_index > 0) { - log_trace(class, nestmates)("Type %s is a dynamic nest member of %s: the NestHost attribute in the current class is ignored", - this->external_name(), - host->external_name()); + msg = "(the NestHost attribute in the current class is ignored)"; } else if (_nest_members != NULL && _nest_members != Universe::the_empty_short_array()) { - log_trace(class, nestmates)("Type %s is a dynamic nest member of %s: the NestMembers attribute in the current class is ignored", - this->external_name(), - host->external_name()); + msg = "(the NestMembers attribute in the current class is ignored)"; } + log_trace(class, nestmates)("Injected type %s into the nest of %s %s", + this->external_name(), + host->external_name(), + msg); } // set dynamic nest host _nest_host = host; @@ -393,23 +384,21 @@ // check if 'this' and k are nestmates (same nest_host), or k is our nest_host, // or we are k's nest_host - all of which is covered by comparing the two -// resolved_nest_hosts +// resolved_nest_hosts. +// Any exceptions (i.e. VMEs) are propagated. bool InstanceKlass::has_nestmate_access_to(InstanceKlass* k, TRAPS) { assert(this != k, "this should be handled by higher-level code"); // Per JVMS 5.4.4 we first resolve and validate the current class, then - // the target class k. Resolution exceptions will be passed on by upper - // layers. IncompatibleClassChangeErrors from membership validation failures - // will also be passed through. + // the target class k. - Symbol* icce = vmSymbols::java_lang_IncompatibleClassChangeError(); - InstanceKlass* cur_host = nest_host(icce, CHECK_false); + InstanceKlass* cur_host = nest_host(CHECK_false); if (cur_host == NULL) { return false; } - Klass* k_nest_host = k->nest_host(icce, CHECK_false); + Klass* k_nest_host = k->nest_host(CHECK_false); if (k_nest_host == NULL) { return false; } @@ -497,6 +486,7 @@ _nest_members(NULL), _nest_host_index(0), _nest_host(NULL), + _nest_host_res_error(NULL), _record_components(NULL), _static_field_size(parser.static_field_size()), _nonstatic_oop_map_size(nonstatic_oop_map_size(parser.total_oop_map_count())), @@ -2482,6 +2472,7 @@ _oop_map_cache = NULL; // clear _nest_host to ensure re-load at runtime _nest_host = NULL; + _nest_host_res_error = NULL; _package_entry = NULL; _dep_context_last_cleaned = 0; } @@ -2647,6 +2638,12 @@ // class can't be referenced anymore). if (_array_name != NULL) _array_name->decrement_refcount(); FREE_C_HEAP_ARRAY(char, _source_debug_extension); + + // deallocate memoized nest-host resolution error + if (_nest_host_res_error != NULL) { + FREE_C_HEAP_ARRAY(char, _nest_host_res_error); + _nest_host_res_error = NULL; + } } void InstanceKlass::set_source_debug_extension(const char* array, int length) { --- old/src/hotspot/share/oops/instanceKlass.hpp 2020-03-08 19:03:08.574726791 -0400 +++ new/src/hotspot/share/oops/instanceKlass.hpp 2020-03-08 19:03:07.419713978 -0400 @@ -195,10 +195,16 @@ // that is the nest-host of this class. This data has not been validated. jushort _nest_host_index; - // Resolved nest-host klass: either true nest-host or self if we are not nested. + // Resolved nest-host klass: either true nest-host or self if we are not + // nested, or an error occurred resolving or validating the nominated + // nest-host. Can also be set directly by JDK API's that establish nest + // relationships. // By always being set it makes nest-member access checks simpler. InstanceKlass* _nest_host; + // Used to record a reason for nest-host resolution/validation failures. + const char* _nest_host_res_error; + // The contents of the Record attribute. Array* _record_components; @@ -484,14 +490,14 @@ bool has_nest_member(InstanceKlass* k, TRAPS) const; public: - // Returns nest-host class, resolving and validating it if needed - // Returns NULL if an exception occurs during loading, or validation fails - InstanceKlass* nest_host(Symbol* validationException, TRAPS); + // Used to construct informative IllegalAccessError messages at a higher level. + // Returns NULL if there was no error. + const char* nest_host_resolution_error() { return _nest_host_res_error; } + // Returns nest-host class, resolving and validating it if needed. + // Returns NULL if resolution is not possible from the calling context. + InstanceKlass* nest_host(TRAPS); // Check if this klass is a nestmate of k - resolves this nest-host and k's bool has_nestmate_access_to(InstanceKlass* k, TRAPS); - // Returns the runtime nest host. If static nest host is valid, set the nest host; - // otherwise this klass is the host of a nest; all errors are ignored - InstanceKlass* runtime_nest_host(TRAPS); enum InnerClassAttributeOffset { // From http://mirror.eng/products/jdk/1.1/docs/guide/innerclasses/spec/innerclasses.doc10.html#18814 --- old/src/hotspot/share/prims/jvm.cpp 2020-03-08 19:03:13.180777889 -0400 +++ new/src/hotspot/share/prims/jvm.cpp 2020-03-08 19:03:12.021765031 -0400 @@ -1017,7 +1017,7 @@ InstanceKlass* host_class = NULL; if (is_nestmate) { - host_class = InstanceKlass::cast(lookup_k)->runtime_nest_host(CHECK_NULL); + host_class = InstanceKlass::cast(lookup_k)->nest_host(CHECK_NULL); } if (log_is_enabled(Info, class, nestmates)) { @@ -2051,8 +2051,7 @@ Klass* c = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(current)); assert(c->is_instance_klass(), "must be"); InstanceKlass* ck = InstanceKlass::cast(c); - // Don't post exceptions if validation fails - InstanceKlass* host = ck->nest_host(NULL, THREAD); + InstanceKlass* host = ck->nest_host(THREAD); return (jclass) (host == NULL ? NULL : JNIHandles::make_local(THREAD, host->java_mirror())); } @@ -2065,56 +2064,89 @@ Klass* c = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(current)); assert(c->is_instance_klass(), "must be"); InstanceKlass* ck = InstanceKlass::cast(c); - // Get the nest host for this nest - throw ICCE if validation fails - Symbol* icce = vmSymbols::java_lang_IncompatibleClassChangeError(); - InstanceKlass* host = ck->nest_host(icce, CHECK_NULL); + InstanceKlass* host = ck->nest_host(THREAD); + + const bool doLog = log_is_enabled(Trace, class, nestmates); + + if (doLog) { + ResourceMark rm(THREAD); + log_trace(class, nestmates)("Calling GetNestMembers for type %s with nest-host %s", + ck->external_name(), host->external_name()); + } { JvmtiVMObjectAllocEventCollector oam; Array* members = host->nest_members(); int length = members == NULL ? 0 : members->length(); + + if (doLog) { + log_trace(class, nestmates)(" - host has %d listed nest members", length); + } + // nest host is first in the array so make it one bigger objArrayOop r = oopFactory::new_objArray(SystemDictionary::Class_klass(), length + 1, CHECK_NULL); - objArrayHandle result (THREAD, r); + objArrayHandle result(THREAD, r); result->obj_at_put(0, host->java_mirror()); if (length != 0) { - int i; - for (i = 0; i < length; i++) { - int cp_index = members->at(i); - Klass* k = host->constants()->klass_at(cp_index, CHECK_NULL); - if (k->is_instance_klass()) { - InstanceKlass* nest_host_k = - InstanceKlass::cast(k)->nest_host(icce, CHECK_NULL); - if (nest_host_k == host) { - result->obj_at_put(i+1, k->java_mirror()); - } - else { - // k's nest host is legal but it isn't our host so - // throw ICCE - ResourceMark rm(THREAD); - Exceptions::fthrow(THREAD_AND_LOCATION, - icce, - "%s.getNestMembers: Nest member %s in %s declares a different nest host of %s", - c->external_name(), - k->external_name(), - host->external_name(), - nest_host_k->external_name() - ); - return NULL; - } - } - else { - // we have a bad nest member entry - throw ICCE - ResourceMark rm(THREAD); - Exceptions::fthrow(THREAD_AND_LOCATION, - icce, - "Class %s can not be a nest member of %s", - k->external_name(), - host->external_name() - ); - return NULL; - } + int count = 0; + for (int i = 0; i < length; i++) { + int cp_index = members->at(i); + Klass* k = host->constants()->klass_at(cp_index, THREAD); + if (HAS_PENDING_EXCEPTION) { + if (PENDING_EXCEPTION->is_a(SystemDictionary::VirtualMachineError_klass())) { + return NULL; // propagate VMEs + } + if (doLog) { + ResourceMark rm(THREAD); + stringStream ss; + char* target_member_class = host->constants()->klass_name_at(cp_index)->as_C_string(); + ss.print(" - resolution of nest member %s failed: ", target_member_class); + java_lang_Throwable::print(PENDING_EXCEPTION, &ss); + log_trace(class, nestmates)("%s", ss.as_string()); + } + CLEAR_PENDING_EXCEPTION; + continue; + } + if (k->is_instance_klass()) { + InstanceKlass* ik = InstanceKlass::cast(k); + InstanceKlass* nest_host_k = ik->nest_host(CHECK_NULL); + if (nest_host_k == host) { + result->obj_at_put(count+1, k->java_mirror()); + count++; + if (doLog) { + ResourceMark rm(THREAD); + log_trace(class, nestmates)(" - [%d] = %s", count, ik->external_name()); + } + } else { + if (doLog) { + ResourceMark rm(THREAD); + log_trace(class, nestmates)(" - skipping member %s with different host %s", + ik->external_name(), nest_host_k->external_name()); + } + } + } else { + if (doLog) { + ResourceMark rm(THREAD); + log_trace(class, nestmates)(" - skipping member %s that is not an instance class", + k->external_name()); + } + } + } + if (count < length) { + // we had invalid entries so we need to compact the array + if (doLog) { + ResourceMark rm(THREAD); + log_trace(class, nestmates)(" - compacting array from length %d to %d", + length + 1, count + 1); + } + objArrayOop r2 = oopFactory::new_objArray(SystemDictionary::Class_klass(), + count + 1, CHECK_NULL); + objArrayHandle result2(THREAD, r2); + for (int i = 0; i < count + 1; i++) { + result2->obj_at_put(i, result->obj_at(i)); + } + return (jobjectArray)JNIHandles::make_local(THREAD, result2()); } } else { --- old/src/hotspot/share/utilities/ostream.cpp 2020-03-08 19:03:23.397891233 -0400 +++ new/src/hotspot/share/utilities/ostream.cpp 2020-03-08 19:03:22.257878586 -0400 @@ -368,8 +368,9 @@ zero_terminate(); } -char* stringStream::as_string() const { - char* copy = NEW_RESOURCE_ARRAY(char, buffer_pos + 1); +char* stringStream::as_string(bool c_heap) const { + char* copy = c_heap ? + NEW_C_HEAP_ARRAY(char, buffer_pos + 1, mtInternal) : NEW_RESOURCE_ARRAY(char, buffer_pos + 1); strncpy(copy, buffer, buffer_pos); copy[buffer_pos] = 0; // terminating null return copy; --- old/src/hotspot/share/utilities/ostream.hpp 2020-03-08 19:03:28.880952059 -0400 +++ new/src/hotspot/share/utilities/ostream.hpp 2020-03-08 19:03:27.753939557 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -215,7 +215,8 @@ size_t size() const { return buffer_pos; } const char* base() const { return buffer; } void reset(); - char* as_string() const; + // copy to a resource, or C-heap, array as requested + char* as_string(bool c_heap = false) const; }; class fileStream : public outputStream { --- old/src/java.base/share/classes/java/lang/Class.java 2020-03-08 19:03:34.456013907 -0400 +++ new/src/java.base/share/classes/java/lang/Class.java 2020-03-08 19:03:33.308001171 -0400 @@ -4021,47 +4021,32 @@ /** * Returns the nest host of the nest to which the class * or interface represented by this {@code Class} object belongs. - * Every class and interface is a member of exactly one nest. - * A class or interface that is not recorded as belonging to a nest - * belongs to the nest consisting only of itself, and is the nest - * host. - * - *

Each of the {@code Class} objects representing array types, - * primitive types, and {@code void} returns {@code this} to indicate - * that the represented entity belongs to the nest consisting only of - * itself, and is the nest host. - * - *

If there is a {@linkplain LinkageError linkage error} accessing - * the nest host, or if this class or interface is not enumerated as - * a member of the nest by the nest host, then it is considered to belong - * to its own nest and {@code this} is returned as the host. + * Every class and interface belongs to exactly one nest. * - *

If this class is a {@linkplain Class#isHiddenClass() hidden class} - * created by calling - * {@link MethodHandles.Lookup#defineHiddenClass(byte[], boolean, MethodHandles.Lookup.ClassOption...) - * Lookup::defineHiddenClass} with {@link MethodHandles.Lookup.ClassOption#NESTMATE - * NESTMATE} option, then the hidden class is added as a member to - * the nest of a {@linkplain MethodHandles.Lookup#lookupClass() lookup class} - * dynamically and it has the same nest host as the lookup class. - * - * @apiNote A {@code class} file of version 55.0 or greater may record the - * host of the nest to which it belongs by using the {@code NestHost} - * attribute (JVMS 4.7.28). Alternatively, a {@code class} file of - * version 55.0 or greater may act as a nest host by enumerating the nest's - * other members with the - * {@code NestMembers} attribute (JVMS 4.7.29). - * A {@code class} file of version 54.0 or lower does not use these - * attributes. + * If the nest host of this class or interface has previously + * been determined, then this method returns the nest host. + * If the nest host of this class or interface has + * not previously been determined, then this method determines the nest + * host using the algorithm of JVMS 5.4.4, and returns it. + * + * Often, a class or interface belongs to a nest consisting only of itself, + * in which case this method returns {@code this} to indicate that the class + * or interface is the nest host. + * + *

If this {@code Class} object represents a primitive type, an array type, + * or {@code void}, then this method returns {@code this}, + * indicating that the represented entity belongs to the nest consisting only of + * itself, and is the nest host. * * @return the nest host of this class or interface * * @throws SecurityException - * If the returned class is not the current class, and - * if a security manager, s, is present and the caller's - * class loader is not the same as or an ancestor of the class - * loader for the returned class and invocation of {@link - * SecurityManager#checkPackageAccess s.checkPackageAccess()} - * denies access to the package of the returned class + * If the returned class is not the current class, and + * if a security manager, s, is present and the caller's + * class loader is not the same as or an ancestor of the class + * loader for the returned class and invocation of {@link + * SecurityManager#checkPackageAccess s.checkPackageAccess()} + * denies access to the package of the returned class * @since 11 * @jvms 4.7.28 The {@code NestHost} Attribute * @jvms 4.7.29 The {@code NestMembers} Attribute @@ -4076,12 +4061,9 @@ Class host = this.nest; if (host == null) { host = getNestHost0(); - // if null then nest membership validation failed, so we - // act as-if we have no nest-host attribute - if (host == null || host == this) { + if (host == this) { return this.nest = this; } - this.nest = host; } // returning a different class requires a security check SecurityManager sm = System.getSecurityManager(); @@ -4089,7 +4071,7 @@ checkPackageAccess(sm, ClassLoader.getClassLoader(Reflection.getCallerClass()), true); } - return host; + return (this.nest = host); } // keep a strong reference to the nest host @@ -4125,46 +4107,45 @@ * Returns an array containing {@code Class} objects representing all the * classes and interfaces that are members of the nest to which the class * or interface represented by this {@code Class} object belongs. - * The {@linkplain #getNestHost() nest host} of that nest is the zeroth - * element of the array. Subsequent elements represent any classes or - * interfaces that are recorded by the nest host as being members of - * the nest; the order of such elements is unspecified. Duplicates are - * permitted. - * If the nest host of that nest does not enumerate any members, then the - * array has a single element containing {@code this}. * - *

Each of the {@code Class} objects representing array types, - * primitive types, and {@code void} returns an array containing only - * {@code this}. + * First, this method obtains the {@linkplain #getNestHost() nest host}, {@code H}, of the nest + * to which the class or interface represented by this {@code Class} object belongs. + * The zeroth element of the returned array is {@code H}. + * + * Then, for each class or interface {@code C} which is recorded by {@code H} as being a member + * of its nest, this method attempts to obtain the {@code Class} object for {@code C} + * (using {@linkplain #getClassLoader() the defining class loader} of the current {@code Class} object), + * and then obtains the {@linkplain #getNestHost() nest host} of the nest to which {@code C} belongs. + * The classes and interfaces which are recorded by {@code H} as being members of its nest, + * and for which {@code H} can be determined as their nest host, are indicated by subsequent elements + * of the returned array. The order of such elements is unspecified. + * Duplicates are permitted. * - *

This method validates that, for each class or interface which is - * recorded as a member of the nest by the nest host, that class or - * interface records itself as a member of that same nest. Any exceptions - * that occur during this validation are rethrown by this method. + *

If this {@code Class} object represents a primitive type, an array type, + * or {@code void}, then this method returns a single-element array containing + * {@code this}. * * @apiNote - * This method returns the nest members listed in the {@code NestMembers} - * attribute. The returned array does not include any hidden class that - * were added to the nest of this class via + * The returned array includes only the nest members recorded in the {@code NestMembers} + * attribute, and not any hidden classes that were added to the nest via * {@link MethodHandles.Lookup#defineHiddenClass(byte[], boolean, MethodHandles.Lookup.ClassOption...) * Lookup::defineHiddenClass}. * * @return an array of all classes and interfaces in the same nest as * this class * - * @throws LinkageError - * If there is any problem loading or validating a nest member or - * its nest host * @throws SecurityException - * If any returned class is not the current class, and - * if a security manager, s, is present and the caller's - * class loader is not the same as or an ancestor of the class - * loader for that returned class and invocation of {@link - * SecurityManager#checkPackageAccess s.checkPackageAccess()} - * denies access to the package of that returned class + * If any returned class is not the current class, and + * if a security manager, s, is present and the caller's + * class loader is not the same as or an ancestor of the class + * loader for that returned class and invocation of {@link + * SecurityManager#checkPackageAccess s.checkPackageAccess()} + * denies access to the package of that returned class * * @since 11 * @see #getNestHost() + * @jvms 4.7.28 The {@code NestHost} Attribute + * @jvms 4.7.29 The {@code NestMembers} Attribute */ @CallerSensitive public Class[] getNestMembers() { --- old/test/hotspot/jtreg/runtime/Nestmates/membership/TestNestmateMembership.java 2020-03-08 19:03:40.018075610 -0400 +++ new/test/hotspot/jtreg/runtime/Nestmates/membership/TestNestmateMembership.java 2020-03-08 19:03:38.888063074 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -697,8 +697,8 @@ check_expected(expected, msg); } - msg = "class TestNestmateMembership$CallerNoHost tried to access " + - "private method 'void TestNestmateMembership$Target.m()'"; + msg = "class TestNestmateMembership$CallerNoHost tried to access private " + + "method 'void TestNestmateMembership$Target.m()'"; try { CallerNoHost.invokeTarget(); throw new Error("Missing IllegalAccessError: " + msg); @@ -720,19 +720,21 @@ static void test_SelfHostInvoke() throws Throwable { System.out.println("Testing for class that lists itself as nest-host"); String msg = "Type TestNestmateMembership$TargetSelfHost (loader: 'app') is not a nest member" + - " of TestNestmateMembership$TargetSelfHost (loader: 'app'): current type is not listed as a nest member"; + " of type TestNestmateMembership$TargetSelfHost (loader: 'app'): current type is not listed as a nest member)"; try { Caller.invokeTargetSelfHost(); - throw new Error("Missing IncompatibleClassChangeError: " + msg); + throw new Error("Missing IllegalAccessError: " + msg); } - catch (IncompatibleClassChangeError expected) { + catch (IllegalAccessError expected) { check_expected(expected, msg); } + msg = "class TestNestmateMembership$Caller cannot access a member of class " + + "TestNestmateMembership$TargetSelfHost with modifiers \"private static\""; try { Caller.invokeTargetSelfHostReflectively(); - throw new Error("Missing IncompatibleClassChangeError: " + msg); + throw new Error("Missing IllegalAccessError: " + msg); } - catch (IncompatibleClassChangeError expected) { + catch (IllegalAccessException expected) { check_expected(expected, msg); } msg = "no such method: TestNestmateMembership$TargetSelfHost.m()void/invokeStatic"; @@ -745,43 +747,42 @@ } msg = "Type TestNestmateMembership$CallerSelfHost (loader: 'app') is not a nest member" + - " of TestNestmateMembership$CallerSelfHost (loader: 'app'): current type is not listed as a nest member"; + " of type TestNestmateMembership$CallerSelfHost (loader: 'app'): current type is not listed as a nest member"; try { CallerSelfHost.invokeTarget(); - throw new Error("Missing IncompatibleClassChangeError: " + msg); + throw new Error("Missing IllegalAccessError: " + msg); } - catch (IncompatibleClassChangeError expected) { + catch (IllegalAccessError expected) { check_expected(expected, msg); } - msg = "Type TestNestmateMembership$CallerSelfHost (loader: 'app') is not a nest member" + - " of TestNestmateMembership$CallerSelfHost (loader: 'app'): current type is not listed as a nest member"; try { CallerSelfHost.invokeTargetSelfHost(); - throw new Error("Missing IncompatibleClassChangeError: " + msg); + throw new Error("Missing IllegalAccessError: " + msg); } - catch (IncompatibleClassChangeError expected) { + catch (IllegalAccessError expected) { check_expected(expected, msg); } } static void test_MissingHostInvoke() throws Throwable { System.out.println("Testing for nest-host class that does not exist"); - String msg = "Unable to load nest-host class (NoTargetMissingHost) of " + - "TestNestmateMembership$TargetMissingHost"; - String cause_msg = "NoTargetMissingHost"; + String msg = "Nest host resolution of TestNestmateMembership$TargetMissingHost with host" + + " NoTargetMissingHost failed: java.lang.NoClassDefFoundError: NoTargetMissingHost"; try { Caller.invokeTargetMissingHost(); - throw new Error("Missing NoClassDefFoundError: " + msg); + throw new Error("Missing IllegalAccessError: " + msg); } - catch (NoClassDefFoundError expected) { - check_expected(expected, msg, cause_msg); + catch (IllegalAccessError expected) { + check_expected(expected, msg); } + msg = "class TestNestmateMembership$Caller cannot access a member of class" + + " TestNestmateMembership$TargetMissingHost with modifiers \"private static\""; try { Caller.invokeTargetMissingHostReflectively(); - throw new Error("Missing NoClassDefFoundError: " + msg); + throw new Error("Missing IllegalAccessException: " + msg); } - catch (NoClassDefFoundError expected) { - check_expected(expected, msg, cause_msg); + catch (IllegalAccessException expected) { + check_expected(expected, msg); } msg = "no such method: TestNestmateMembership$TargetMissingHost.m()void/invokeStatic"; try { @@ -800,44 +801,42 @@ check_expected(expected, msg); } - msg = "Unable to load nest-host class (NoCallerMissingHost) of " + - "TestNestmateMembership$CallerMissingHost"; - cause_msg = "NoCallerMissingHost"; + msg = "Nest host resolution of TestNestmateMembership$CallerMissingHost with host" + + " NoCallerMissingHost failed: java.lang.NoClassDefFoundError: NoCallerMissingHost"; try { CallerMissingHost.invokeTarget(); - throw new Error("Missing NoClassDefFoundError: " + msg); + throw new Error("Missing IllegalAccessError: " + msg); } - catch (NoClassDefFoundError expected) { - check_expected(expected, msg, cause_msg); + catch (IllegalAccessError expected) { + check_expected(expected, msg); } - msg = "Unable to load nest-host class (NoCallerMissingHost) of "+ - "TestNestmateMembership$CallerMissingHost"; - cause_msg = "NoCallerMissingHost"; try { CallerMissingHost.invokeTargetMissingHost(); - throw new Error("Missing NoClassDefFoundError: " + msg); + throw new Error("Missing IllegalAccessError: " + msg); } - catch (NoClassDefFoundError expected) { - check_expected(expected, msg, cause_msg); + catch (IllegalAccessError expected) { + check_expected(expected, msg); } } static void test_NotInstanceHostInvoke() throws Throwable { System.out.println("Testing for nest-host class that is not an instance class"); String msg = "Type TestNestmateMembership$TargetNotInstanceHost (loader: 'app') is not a "+ - "nest member of [LInvalidNestHost; (loader: 'app'): current type is not listed as a nest member"; + "nest member of type [LInvalidNestHost; (loader: 'app'): host is not an instance class"; try { Caller.invokeTargetNotInstanceHost(); - throw new Error("Missing IncompatibleClassChangeError: " + msg); + throw new Error("Missing IllegalAccessError: " + msg); } - catch (IncompatibleClassChangeError expected) { + catch (IllegalAccessError expected) { check_expected(expected, msg); } + msg = "class TestNestmateMembership$Caller cannot access a member of class "+ + "TestNestmateMembership$TargetNotInstanceHost with modifiers \"private static\""; try { Caller.invokeTargetNotInstanceHostReflectively(); - throw new Error("Missing IncompatibleClassChangeError: " + msg); + throw new Error("Missing IllegalAccessException: " + msg); } - catch (IncompatibleClassChangeError expected) { + catch (IllegalAccessException expected) { check_expected(expected, msg); } msg = "no such method: TestNestmateMembership$TargetNotInstanceHost.m()void/invokeStatic"; @@ -849,42 +848,42 @@ check_expected(expected, msg); } - msg = "Type TestNestmateMembership$CallerNotInstanceHost (loader: 'app') is not a "+ - "nest member of [LInvalidNestHost; (loader: 'app'): current type is not listed as a nest member"; + msg = "Type TestNestmateMembership$CallerNotInstanceHost (loader: 'app') is not a " + + "nest member of type [LInvalidNestHost; (loader: 'app'): host is not an instance class"; try { CallerNotInstanceHost.invokeTarget(); - throw new Error("Missing IncompatibleClassChangeError: " + msg); + throw new Error("Missing IllegalAccessError: " + msg); } - catch (IncompatibleClassChangeError expected) { + catch (IllegalAccessError expected) { check_expected(expected, msg); } - msg = "Type TestNestmateMembership$CallerNotInstanceHost (loader: 'app') is not a "+ - "nest member of [LInvalidNestHost; (loader: 'app'): current type is not listed as a nest member"; try { CallerNotInstanceHost.invokeTargetNotInstanceHost(); - throw new Error("Missing IncompatibleClassChangeError: " + msg); + throw new Error("Missing IllegalAccessError: " + msg); } - catch (IncompatibleClassChangeError expected) { + catch (IllegalAccessError expected) { check_expected(expected, msg); } } static void test_NotOurHostInvoke() throws Throwable { System.out.println("Testing for nest-host class that does not list us in its nest"); - String msg = "Type TestNestmateMembership$TargetNotOurHost (loader: 'app') is not a nest member" + - " of InvalidNestHost (loader: 'app'): current type is not listed as a nest member"; + String msg = "Type TestNestmateMembership$TargetNotOurHost (loader: 'app') is not a " + + "nest member of type InvalidNestHost (loader: 'app'): current type is not listed as a nest member"; try { Caller.invokeTargetNotOurHost(); - throw new Error("Missing IncompatibleClassChangeError: " + msg); + throw new Error("Missing IllegalAccessError: " + msg); } - catch (IncompatibleClassChangeError expected) { + catch (IllegalAccessError expected) { check_expected(expected, msg); } + msg = "class TestNestmateMembership$Caller cannot access a member of class " + + "TestNestmateMembership$TargetNotOurHost with modifiers \"private static\""; try { Caller.invokeTargetNotOurHostReflectively(); - throw new Error("Missing IncompatibleClassChangeError: " + msg); + throw new Error("Missing IllegalAccessException: " + msg); } - catch (IncompatibleClassChangeError expected) { + catch (IllegalAccessException expected) { check_expected(expected, msg); } msg = "no such method: TestNestmateMembership$TargetNotOurHost.m()void/invokeStatic"; @@ -897,21 +896,19 @@ } msg = "Type TestNestmateMembership$CallerNotOurHost (loader: 'app') is not a nest member" + - " of InvalidNestHost (loader: 'app'): current type is not listed as a nest member"; + " of type InvalidNestHost (loader: 'app'): current type is not listed as a nest member"; try { CallerNotOurHost.invokeTarget(); - throw new Error("Missing IncompatibleClassChangeError: " + msg); + throw new Error("Missing IllegalAccessError: " + msg); } - catch (IncompatibleClassChangeError expected) { + catch (IllegalAccessError expected) { check_expected(expected, msg); } - msg = "Type TestNestmateMembership$CallerNotOurHost (loader: 'app') is not a nest member" + - " of InvalidNestHost (loader: 'app'): current type is not listed as a nest member"; try { CallerNotOurHost.invokeTargetNotOurHost(); - throw new Error("Missing IncompatibleClassChangeError: " + msg); + throw new Error("Missing IllegalAccessError: " + msg); } - catch (IncompatibleClassChangeError expected) { + catch (IllegalAccessError expected) { check_expected(expected, msg); } } @@ -919,19 +916,19 @@ static void test_WrongPackageHostInvoke() { System.out.println("Testing for nest-host and nest-member in different packages"); String msg = "Type P2.PackagedNestHost2$Member (loader: 'app') is not a nest member of " + - "P1.PackagedNestHost (loader: 'app'): types are in different packages"; + "type P1.PackagedNestHost (loader: 'app'): types are in different packages"; try { P1.PackagedNestHost.doInvoke(); - throw new Error("Missing IncompatibleClassChangeError: " + msg); + throw new Error("Missing IllegalAccessError: " + msg); } - catch (IncompatibleClassChangeError expected) { + catch (IllegalAccessError expected) { check_expected(expected, msg); } try { P2.PackagedNestHost2.Member.doInvoke(); - throw new Error("Missing IncompatibleClassChangeError: " + msg); + throw new Error("Missing IllegalAccessError: " + msg); } - catch (IncompatibleClassChangeError expected) { + catch (IllegalAccessError expected) { check_expected(expected, msg); } } @@ -953,9 +950,9 @@ "method 'void TestNestmateMembership$TargetNoHost.()'"; try { Caller.newTargetNoHost(); - throw new Error("Missing IncompatibleClassChangeError: " + msg); + throw new Error("Missing IllegalAccessError: " + msg); } - catch (IncompatibleClassChangeError expected) { + catch (IllegalAccessError expected) { check_expected(expected, msg); } msg = "class TestNestmateMembership$Caller cannot access a member of class " + @@ -980,18 +977,18 @@ "method 'void TestNestmateMembership$Target.()'"; try { CallerNoHost.newTarget(); - throw new Error("Missing IncompatibleClassChangeError: " + msg); + throw new Error("Missing IllegalAccessError: " + msg); } - catch (IncompatibleClassChangeError expected) { + catch (IllegalAccessError expected) { check_expected(expected, msg); } msg = "class TestNestmateMembership$CallerNoHost tried to access private " + "method 'void TestNestmateMembership$TargetNoHost.()'"; try { CallerNoHost.newTargetNoHost(); - throw new Error("Missing IncompatibleClassChangeError: " + msg); + throw new Error("Missing IllegalAccessError: " + msg); } - catch (IncompatibleClassChangeError expected) { + catch (IllegalAccessError expected) { check_expected(expected, msg); } } @@ -999,19 +996,21 @@ static void test_SelfHostConstruct() throws Throwable { System.out.println("Testing for class that lists itself as nest-host"); String msg = "Type TestNestmateMembership$TargetSelfHost (loader: 'app') is not a nest member" + - " of TestNestmateMembership$TargetSelfHost (loader: 'app'): current type is not listed as a nest member"; + " of type TestNestmateMembership$TargetSelfHost (loader: 'app'): current type is not listed as a nest member"; try { Caller.newTargetSelfHost(); - throw new Error("Missing IncompatibleClassChangeError: " + msg); + throw new Error("Missing IllegalAccessError: " + msg); } - catch (IncompatibleClassChangeError expected) { + catch (IllegalAccessError expected) { check_expected(expected, msg); } + msg = "class TestNestmateMembership$Caller cannot access a member of class " + + "TestNestmateMembership$TargetSelfHost with modifiers \"private\""; try { Caller.newTargetSelfHostReflectively(); - throw new Error("Missing IncompatibleClassChangeError: " + msg); + throw new Error("Missing IllegalAccessException: " + msg); } - catch (IncompatibleClassChangeError expected) { + catch (IllegalAccessException expected) { check_expected(expected, msg); } msg = "no such constructor: TestNestmateMembership$TargetSelfHost.()void/newInvokeSpecial"; @@ -1024,43 +1023,42 @@ } msg = "Type TestNestmateMembership$CallerSelfHost (loader: 'app') is not a nest member" + - " of TestNestmateMembership$CallerSelfHost (loader: 'app'): current type is not listed as a nest member"; + " of type TestNestmateMembership$CallerSelfHost (loader: 'app'): current type is not listed as a nest member"; try { CallerSelfHost.newTarget(); - throw new Error("Missing IncompatibleClassChangeError: " + msg); + throw new Error("Missing IllegalAccessError: " + msg); } - catch (IncompatibleClassChangeError expected) { + catch (IllegalAccessError expected) { check_expected(expected, msg); } - msg = "Type TestNestmateMembership$CallerSelfHost (loader: 'app') is not a nest member" + - " of TestNestmateMembership$CallerSelfHost (loader: 'app'): current type is not listed as a nest member"; try { CallerSelfHost.newTargetSelfHost(); - throw new Error("Missing IncompatibleClassChangeError: " + msg); + throw new Error("Missing IllegalAccessError: " + msg); } - catch (IncompatibleClassChangeError expected) { + catch (IllegalAccessError expected) { check_expected(expected, msg); } } static void test_MissingHostConstruct() throws Throwable { System.out.println("Testing for nest-host class that does not exist"); - String msg = "Unable to load nest-host class (NoTargetMissingHost) of " + - "TestNestmateMembership$TargetMissingHost"; - String cause_msg = "NoTargetMissingHost"; + String msg = "Nest host resolution of TestNestmateMembership$TargetMissingHost with " + + "host NoTargetMissingHost failed: java.lang.NoClassDefFoundError: NoTargetMissingHost"; try { Caller.newTargetMissingHost(); - throw new Error("Missing NoClassDefFoundError: " + msg); + throw new Error("Missing IllegalAccessError: " + msg); } - catch (NoClassDefFoundError expected) { - check_expected(expected, msg, cause_msg); + catch (IllegalAccessError expected) { + check_expected(expected, msg); } + msg = "class TestNestmateMembership$Caller cannot access a member of class " + + "TestNestmateMembership$TargetMissingHost with modifiers \"private\""; try { Caller.newTargetMissingHostReflectively(); - throw new Error("Missing NoClassDefFoundError: " + msg); + throw new Error("Missing IllegalAccessException: " + msg); } - catch (NoClassDefFoundError expected) { - check_expected(expected, msg, cause_msg); + catch (IllegalAccessException expected) { + check_expected(expected, msg); } msg = "no such constructor: TestNestmateMembership$TargetMissingHost.()void/newInvokeSpecial"; try { @@ -1071,44 +1069,42 @@ check_expected(expected, msg); } - msg = "Unable to load nest-host class (NoCallerMissingHost) of " + - "TestNestmateMembership$CallerMissingHost"; - cause_msg = "NoCallerMissingHost"; + msg = "Nest host resolution of TestNestmateMembership$CallerMissingHost with host " + + "NoCallerMissingHost failed: java.lang.NoClassDefFoundError: NoCallerMissingHost"; try { CallerMissingHost.newTarget(); - throw new Error("Missing NoClassDefFoundError: " + msg); + throw new Error("Missing IllegalAccessError: " + msg); } - catch (NoClassDefFoundError expected) { - check_expected(expected, msg, cause_msg); + catch (IllegalAccessError expected) { + check_expected(expected, msg); } - msg = "Unable to load nest-host class (NoCallerMissingHost) of "+ - "TestNestmateMembership$CallerMissingHost"; - cause_msg = "NoCallerMissingHost"; try { CallerMissingHost.newTargetMissingHost(); - throw new Error("Missing NoClassDefFoundError: " + msg); + throw new Error("Missing IllegalAccessError: " + msg); } - catch (NoClassDefFoundError expected) { - check_expected(expected, msg, cause_msg); + catch (IllegalAccessError expected) { + check_expected(expected, msg); } } static void test_NotInstanceHostConstruct() throws Throwable { System.out.println("Testing for nest-host class that is not an instance class"); String msg = "Type TestNestmateMembership$TargetNotInstanceHost (loader: 'app') is not a "+ - "nest member of [LInvalidNestHost; (loader: 'app'): current type is not listed as a nest member"; + "nest member of type [LInvalidNestHost; (loader: 'app'): host is not an instance class"; try { Caller.newTargetNotInstanceHost(); - throw new Error("Missing IncompatibleClassChangeError: " + msg); + throw new Error("Missing IllegalAccessError: " + msg); } - catch (IncompatibleClassChangeError expected) { + catch (IllegalAccessError expected) { check_expected(expected, msg); } + msg = "class TestNestmateMembership$Caller cannot access a member of class " + + "TestNestmateMembership$TargetNotInstanceHost with modifiers \"private\""; try { Caller.newTargetNotInstanceHostReflectively(); - throw new Error("Missing IncompatibleClassChangeError: " + msg); + throw new Error("Missing IllegalAccessException: " + msg); } - catch (IncompatibleClassChangeError expected) { + catch (IllegalAccessException expected) { check_expected(expected, msg); } msg = "no such constructor: TestNestmateMembership$TargetNotInstanceHost.()void/newInvokeSpecial"; @@ -1121,21 +1117,19 @@ } msg = "Type TestNestmateMembership$CallerNotInstanceHost (loader: 'app') is not a "+ - "nest member of [LInvalidNestHost; (loader: 'app'): current type is not listed as a nest member"; + "nest member of type [LInvalidNestHost; (loader: 'app'): host is not an instance class"; try { CallerNotInstanceHost.newTarget(); - throw new Error("Missing IncompatibleClassChangeError: " + msg); + throw new Error("Missing IllegalAccessError: " + msg); } - catch (IncompatibleClassChangeError expected) { + catch (IllegalAccessError expected) { check_expected(expected, msg); } - msg = "Type TestNestmateMembership$CallerNotInstanceHost (loader: 'app') is not a "+ - "nest member of [LInvalidNestHost; (loader: 'app'): current type is not listed as a nest member"; try { CallerNotInstanceHost.newTargetNotInstanceHost(); - throw new Error("Missing IncompatibleClassChangeError: " + msg); + throw new Error("Missing IllegalAccessError: " + msg); } - catch (IncompatibleClassChangeError expected) { + catch (IllegalAccessError expected) { check_expected(expected, msg); } } @@ -1143,19 +1137,21 @@ static void test_NotOurHostConstruct() throws Throwable { System.out.println("Testing for nest-host class that does not list us in its nest"); String msg = "Type TestNestmateMembership$TargetNotOurHost (loader: 'app') is not a nest member" + - " of InvalidNestHost (loader: 'app'): current type is not listed as a nest member"; + " of type InvalidNestHost (loader: 'app'): current type is not listed as a nest member"; try { Caller.newTargetNotOurHost(); - throw new Error("Missing IncompatibleClassChangeError: " + msg); + throw new Error("Missing IllegalAccessError: " + msg); } - catch (IncompatibleClassChangeError expected) { + catch (IllegalAccessError expected) { check_expected(expected, msg); } + msg = "class TestNestmateMembership$Caller cannot access a member of class " + + "TestNestmateMembership$TargetNotOurHost with modifiers \"private\""; try { Caller.newTargetNotOurHostReflectively(); - throw new Error("Missing IncompatibleClassChangeError: " + msg); + throw new Error("Missing IllegalAccessException: " + msg); } - catch (IncompatibleClassChangeError expected) { + catch (IllegalAccessException expected) { check_expected(expected, msg); } msg = "no such constructor: TestNestmateMembership$TargetNotOurHost.()void/newInvokeSpecial"; @@ -1168,21 +1164,21 @@ } msg = "Type TestNestmateMembership$CallerNotOurHost (loader: 'app') is not a nest member" + - " of InvalidNestHost (loader: 'app'): current type is not listed as a nest member"; + " of type InvalidNestHost (loader: 'app'): current type is not listed as a nest member"; try { CallerNotOurHost.newTarget(); - throw new Error("Missing IncompatibleClassChangeError: " + msg); + throw new Error("Missing IllegalAccessError: " + msg); } - catch (IncompatibleClassChangeError expected) { + catch (IllegalAccessError expected) { check_expected(expected, msg); } msg = "Type TestNestmateMembership$CallerNotOurHost (loader: 'app') is not a nest member" + - " of InvalidNestHost (loader: 'app'): current type is not listed as a nest member"; + " of type InvalidNestHost (loader: 'app'): current type is not listed as a nest member"; try { CallerNotOurHost.newTargetNotOurHost(); - throw new Error("Missing IncompatibleClassChangeError: " + msg); + throw new Error("Missing IllegalAccessError: " + msg); } - catch (IncompatibleClassChangeError expected) { + catch (IllegalAccessError expected) { check_expected(expected, msg); } } @@ -1190,19 +1186,19 @@ static void test_WrongPackageHostConstruct() { System.out.println("Testing for nest-host and nest-member in different packages"); String msg = "Type P2.PackagedNestHost2$Member (loader: 'app') is not a nest member of " + - "P1.PackagedNestHost (loader: 'app'): types are in different packages"; + "type P1.PackagedNestHost (loader: 'app'): types are in different packages"; try { P1.PackagedNestHost.doConstruct(); - throw new Error("Missing IncompatibleClassChangeError: " + msg); + throw new Error("Missing IllegalAccessError: " + msg); } - catch (IncompatibleClassChangeError expected) { + catch (IllegalAccessError expected) { check_expected(expected, msg); } try { P2.PackagedNestHost2.Member.doConstruct(); - throw new Error("Missing IncompatibleClassChangeError: " + msg); + throw new Error("Missing IllegalAccessError: " + msg); } - catch (IncompatibleClassChangeError expected) { + catch (IllegalAccessError expected) { check_expected(expected, msg); } } @@ -1224,9 +1220,9 @@ "field TestNestmateMembership$TargetNoHost.f"; try { Caller.getFieldTargetNoHost(); - throw new Error("Missing IncompatibleClassChangeError: " + msg); + throw new Error("Missing IllegalAccessError: " + msg); } - catch (IncompatibleClassChangeError expected) { + catch (IllegalAccessError expected) { check_expected(expected, msg); } msg = "class TestNestmateMembership$Caller cannot access a member of class " + @@ -1251,18 +1247,18 @@ "field TestNestmateMembership$Target.f"; try { CallerNoHost.getFieldTarget(); - throw new Error("Missing IncompatibleClassChangeError: " + msg); + throw new Error("Missing IllegalAccessError: " + msg); } - catch (IncompatibleClassChangeError expected) { + catch (IllegalAccessError expected) { check_expected(expected, msg); } msg = "class TestNestmateMembership$CallerNoHost tried to access private " + "field TestNestmateMembership$TargetNoHost.f"; try { CallerNoHost.getFieldTargetNoHost(); - throw new Error("Missing IncompatibleClassChangeError: " + msg); + throw new Error("Missing IllegalAccessError: " + msg); } - catch (IncompatibleClassChangeError expected) { + catch (IllegalAccessError expected) { check_expected(expected, msg); } } @@ -1270,140 +1266,143 @@ static void test_SelfHostGetField() throws Throwable { System.out.println("Testing for class that lists itself as nest-host"); String msg = "Type TestNestmateMembership$TargetSelfHost (loader: 'app') is not a nest member" + - " of TestNestmateMembership$TargetSelfHost (loader: 'app'): current type is not listed as a nest member"; + " of type TestNestmateMembership$TargetSelfHost (loader: 'app'): current type is not listed as a nest member"; try { Caller.getFieldTargetSelfHost(); - throw new Error("Missing IncompatibleClassChangeError: " + msg); + throw new Error("Missing IllegalAccessError: " + msg); } - catch (IncompatibleClassChangeError expected) { + catch (IllegalAccessError expected) { check_expected(expected, msg); } + msg = "class TestNestmateMembership$Caller cannot access a member of class " + + "TestNestmateMembership$TargetSelfHost with modifiers \"private static\""; try { Caller.getFieldTargetSelfHostReflectively(); - throw new Error("Missing IncompatibleClassChangeError: " + msg); + throw new Error("Missing IllegalAccessException: " + msg); } - catch (IncompatibleClassChangeError expected) { + catch (IllegalAccessException expected) { check_expected(expected, msg); } + msg = "member is private: TestNestmateMembership$TargetSelfHost.f/int/getStatic, " + + "from class TestNestmateMembership$Caller"; try { Caller.getFieldTargetSelfHostMH(); - throw new Error("Missing IncompatibleClassChangeError: " + msg); + throw new Error("Missing IllegalAccessException: " + msg); } - catch (IncompatibleClassChangeError expected) { + catch (IllegalAccessException expected) { check_expected(expected, msg); } msg = "Type TestNestmateMembership$CallerSelfHost (loader: 'app') is not a nest member" + - " of TestNestmateMembership$CallerSelfHost (loader: 'app'): current type is not listed as a nest member"; + " of type TestNestmateMembership$CallerSelfHost (loader: 'app'): current type is not listed as a nest member"; try { CallerSelfHost.getFieldTarget(); - throw new Error("Missing IncompatibleClassChangeError: " + msg); + throw new Error("Missing IllegalAccessError: " + msg); } - catch (IncompatibleClassChangeError expected) { + catch (IllegalAccessError expected) { check_expected(expected, msg); } - msg = "Type TestNestmateMembership$CallerSelfHost (loader: 'app') is not a nest member" + - " of TestNestmateMembership$CallerSelfHost (loader: 'app'): current type is not listed as a nest member"; try { CallerSelfHost.getFieldTargetSelfHost(); - throw new Error("Missing IncompatibleClassChangeError: " + msg); + throw new Error("Missing IllegalAccessError: " + msg); } - catch (IncompatibleClassChangeError expected) { + catch (IllegalAccessError expected) { check_expected(expected, msg); } } static void test_MissingHostGetField() throws Throwable { System.out.println("Testing for nest-host class that does not exist"); - String msg = "Unable to load nest-host class (NoTargetMissingHost) of " + - "TestNestmateMembership$TargetMissingHost"; - String cause_msg = "NoTargetMissingHost"; + String msg = "Nest host resolution of TestNestmateMembership$TargetMissingHost with " + + "host NoTargetMissingHost failed: java.lang.NoClassDefFoundError: NoTargetMissingHost"; try { Caller.getFieldTargetMissingHost(); - throw new Error("Missing NoClassDefFoundError: " + msg); + throw new Error("Missing IllegalAccessError: " + msg); } - catch (NoClassDefFoundError expected) { - check_expected(expected, msg, cause_msg); + catch (IllegalAccessError expected) { + check_expected(expected, msg); } + msg = "class TestNestmateMembership$Caller cannot access a member of class " + + "TestNestmateMembership$TargetMissingHost with modifiers \"private static\""; try { Caller.getFieldTargetMissingHostReflectively(); - throw new Error("Missing NoClassDefFoundError: " + msg); + throw new Error("Missing IllegalAccessException: " + msg); } - catch (NoClassDefFoundError expected) { - check_expected(expected, msg, cause_msg); + catch (IllegalAccessException expected) { + check_expected(expected, msg); } + msg = "member is private: TestNestmateMembership$TargetMissingHost.f/int/getStatic, " + + "from class TestNestmateMembership$Caller"; try { Caller.getFieldTargetMissingHostMH(); - throw new Error("Missing NoClassDefFoundError: " + msg); + throw new Error("Missing IllegalAccessException: " + msg); } - catch (NoClassDefFoundError expected) { - check_expected(expected, msg, cause_msg); + catch (IllegalAccessException expected) { + check_expected(expected, msg); } - msg = "Unable to load nest-host class (NoCallerMissingHost) of " + - "TestNestmateMembership$CallerMissingHost"; - cause_msg = "NoCallerMissingHost"; + msg = "Nest host resolution of TestNestmateMembership$CallerMissingHost with " + + "host NoCallerMissingHost failed: java.lang.NoClassDefFoundError: NoCallerMissingHost"; try { CallerMissingHost.getFieldTarget(); - throw new Error("Missing NoClassDefFoundError: " + msg); + throw new Error("Missing IllegalAccessError: " + msg); } - catch (NoClassDefFoundError expected) { - check_expected(expected, msg, cause_msg); + catch (IllegalAccessError expected) { + check_expected(expected, msg); } - msg = "Unable to load nest-host class (NoCallerMissingHost) of "+ - "TestNestmateMembership$CallerMissingHost"; - cause_msg = "NoCallerMissingHost"; try { CallerMissingHost.getFieldTargetMissingHost(); - throw new Error("Missing NoClassDefFoundError: " + msg); + throw new Error("Missing IllegalAccessError: " + msg); } - catch (NoClassDefFoundError expected) { - check_expected(expected, msg, cause_msg); + catch (IllegalAccessError expected) { + check_expected(expected, msg); } } static void test_NotInstanceHostGetField() throws Throwable { System.out.println("Testing for nest-host class that is not an instance class"); String msg = "Type TestNestmateMembership$TargetNotInstanceHost (loader: 'app') is not a "+ - "nest member of [LInvalidNestHost; (loader: 'app'): current type is not listed as a nest member"; + "nest member of type [LInvalidNestHost; (loader: 'app'): host is not an instance class"; try { Caller.getFieldTargetNotInstanceHost(); - throw new Error("Missing IncompatibleClassChangeError: " + msg); + throw new Error("Missing IllegalAccessError: " + msg); } - catch (IncompatibleClassChangeError expected) { + catch (IllegalAccessError expected) { check_expected(expected, msg); } + msg = "class TestNestmateMembership$Caller cannot access a member of class " + + "TestNestmateMembership$TargetNotInstanceHost with modifiers \"private static\""; try { Caller.getFieldTargetNotInstanceHostReflectively(); - throw new Error("Missing IncompatibleClassChangeError: " + msg); + throw new Error("Missing IllegalAccessException: " + msg); } - catch (IncompatibleClassChangeError expected) { + catch (IllegalAccessException expected) { check_expected(expected, msg); } + msg = "member is private: TestNestmateMembership$TargetNotInstanceHost.f/int/getStatic, " + + "from class TestNestmateMembership$Caller"; try { Caller.getFieldTargetNotInstanceHostMH(); - throw new Error("Missing IncompatibleClassChangeError: " + msg); + throw new Error("Missing IllegalAccessException: " + msg); } - catch (IncompatibleClassChangeError expected) { + catch (IllegalAccessException expected) { check_expected(expected, msg); } msg = "Type TestNestmateMembership$CallerNotInstanceHost (loader: 'app') is not a "+ - "nest member of [LInvalidNestHost; (loader: 'app'): current type is not listed as a nest member"; + "nest member of type [LInvalidNestHost; (loader: 'app'): host is not an instance class"; try { CallerNotInstanceHost.getFieldTarget(); - throw new Error("Missing IncompatibleClassChangeError: " + msg); + throw new Error("Missing IllegalAccessError: " + msg); } - catch (IncompatibleClassChangeError expected) { + catch (IllegalAccessError expected) { check_expected(expected, msg); } - msg = "Type TestNestmateMembership$CallerNotInstanceHost (loader: 'app') is not a "+ - "nest member of [LInvalidNestHost; (loader: 'app'): current type is not listed as a nest member"; try { CallerNotInstanceHost.getFieldTargetNotInstanceHost(); - throw new Error("Missing IncompatibleClassChangeError: " + msg); + throw new Error("Missing IllegalAccessError: " + msg); } - catch (IncompatibleClassChangeError expected) { + catch (IllegalAccessError expected) { check_expected(expected, msg); } } @@ -1411,45 +1410,47 @@ static void test_NotOurHostGetField() throws Throwable { System.out.println("Testing for nest-host class that does not list us in its nest"); String msg = "Type TestNestmateMembership$TargetNotOurHost (loader: 'app') is not a nest member" + - " of InvalidNestHost (loader: 'app'): current type is not listed as a nest member"; + " of type InvalidNestHost (loader: 'app'): current type is not listed as a nest member"; try { Caller.getFieldTargetNotOurHost(); - throw new Error("Missing IncompatibleClassChangeError: " + msg); + throw new Error("Missing IllegalAccessError: " + msg); } - catch (IncompatibleClassChangeError expected) { + catch (IllegalAccessError expected) { check_expected(expected, msg); } + msg = "class TestNestmateMembership$Caller cannot access a member of class " + + "TestNestmateMembership$TargetNotOurHost with modifiers \"private static\""; try { Caller.getFieldTargetNotOurHostReflectively(); - throw new Error("Missing IncompatibleClassChangeError: " + msg); + throw new Error("Missing IllegalAccessException: " + msg); } - catch (IncompatibleClassChangeError expected) { + catch (IllegalAccessException expected) { check_expected(expected, msg); } + msg = "member is private: TestNestmateMembership$TargetNotOurHost.f/int/getStatic, " + + "from class TestNestmateMembership$Caller"; try { Caller.getFieldTargetNotOurHostMH(); - throw new Error("Missing IncompatibleClassChangeError: " + msg); + throw new Error("Missing IllegalAccessException: " + msg); } - catch (IncompatibleClassChangeError expected) { + catch (IllegalAccessException expected) { check_expected(expected, msg); } msg = "Type TestNestmateMembership$CallerNotOurHost (loader: 'app') is not a nest member" + - " of InvalidNestHost (loader: 'app'): current type is not listed as a nest member"; + " of type InvalidNestHost (loader: 'app'): current type is not listed as a nest member"; try { CallerNotOurHost.getFieldTarget(); - throw new Error("Missing IncompatibleClassChangeError: " + msg); + throw new Error("Missing IllegalAccessError: " + msg); } - catch (IncompatibleClassChangeError expected) { + catch (IllegalAccessError expected) { check_expected(expected, msg); } - msg = "Type TestNestmateMembership$CallerNotOurHost (loader: 'app') is not a nest member" + - " of InvalidNestHost (loader: 'app'): current type is not listed as a nest member"; try { CallerNotOurHost.getFieldTargetNotOurHost(); - throw new Error("Missing IncompatibleClassChangeError: " + msg); + throw new Error("Missing IllegalAccessError: " + msg); } - catch (IncompatibleClassChangeError expected) { + catch (IllegalAccessError expected) { check_expected(expected, msg); } } @@ -1457,19 +1458,19 @@ static void test_WrongPackageHostGetField() { System.out.println("Testing for nest-host and nest-member in different packages"); String msg = "Type P2.PackagedNestHost2$Member (loader: 'app') is not a nest member of " + - "P1.PackagedNestHost (loader: 'app'): types are in different packages"; + "type P1.PackagedNestHost (loader: 'app'): types are in different packages"; try { P1.PackagedNestHost.doGetField(); - throw new Error("Missing IncompatibleClassChangeError: " + msg); + throw new Error("Missing IllegalAccessError: " + msg); } - catch (IncompatibleClassChangeError expected) { + catch (IllegalAccessError expected) { check_expected(expected, msg); } try { P2.PackagedNestHost2.Member.doGetField(); - throw new Error("Missing IncompatibleClassChangeError: " + msg); + throw new Error("Missing IllegalAccessError: " + msg); } - catch (IncompatibleClassChangeError expected) { + catch (IllegalAccessError expected) { check_expected(expected, msg); } } @@ -1489,9 +1490,9 @@ "field TestNestmateMembership$TargetNoHost.f"; try { Caller.putFieldTargetNoHost(); - throw new Error("Missing IncompatibleClassChangeError: " + msg); + throw new Error("Missing IllegalAccessError: " + msg); } - catch (IncompatibleClassChangeError expected) { + catch (IllegalAccessError expected) { check_expected(expected, msg); } msg = "class TestNestmateMembership$Caller cannot access a member of class " + @@ -1516,18 +1517,18 @@ "field TestNestmateMembership$Target.f"; try { CallerNoHost.putFieldTarget(); - throw new Error("Missing IncompatibleClassChangeError: " + msg); + throw new Error("Missing IllegalAccessError: " + msg); } - catch (IncompatibleClassChangeError expected) { + catch (IllegalAccessError expected) { check_expected(expected, msg); } msg = "class TestNestmateMembership$CallerNoHost tried to access private " + "field TestNestmateMembership$TargetNoHost.f"; try { CallerNoHost.putFieldTargetNoHost(); - throw new Error("Missing IncompatibleClassChangeError: " + msg); + throw new Error("Missing IllegalAccessError: " + msg); } - catch (IncompatibleClassChangeError expected) { + catch (IllegalAccessError expected) { check_expected(expected, msg); } } @@ -1535,140 +1536,142 @@ static void test_SelfHostPutField() throws Throwable { System.out.println("Testing for class that lists itself as nest-host"); String msg = "Type TestNestmateMembership$TargetSelfHost (loader: 'app') is not a nest member" + - " of TestNestmateMembership$TargetSelfHost (loader: 'app'): current type is not listed as a nest member"; + " of type TestNestmateMembership$TargetSelfHost (loader: 'app'): current type is not listed as a nest member"; try { Caller.putFieldTargetSelfHost(); - throw new Error("Missing IncompatibleClassChangeError: " + msg); + throw new Error("Missing IllegalAccessError: " + msg); } - catch (IncompatibleClassChangeError expected) { + catch (IllegalAccessError expected) { check_expected(expected, msg); } + msg = "class TestNestmateMembership$Caller cannot access a member of class " + + "TestNestmateMembership$TargetSelfHost with modifiers \"private static\""; try { Caller.putFieldTargetSelfHostReflectively(); - throw new Error("Missing IncompatibleClassChangeError: " + msg); + throw new Error("Missing IllegalAccessException: " + msg); } - catch (IncompatibleClassChangeError expected) { + catch (IllegalAccessException expected) { check_expected(expected, msg); } + msg = "member is private: TestNestmateMembership$TargetSelfHost.f/int/putStatic, " + + "from class TestNestmateMembership$Caller"; try { Caller.putFieldTargetSelfHostMH(); - throw new Error("Missing IncompatibleClassChangeError: " + msg); + throw new Error("Missing IllegalAccessException: " + msg); } - catch (IncompatibleClassChangeError expected) { + catch (IllegalAccessException expected) { check_expected(expected, msg); } msg = "Type TestNestmateMembership$CallerSelfHost (loader: 'app') is not a nest member" + - " of TestNestmateMembership$CallerSelfHost (loader: 'app'): current type is not listed as a nest member"; + " of type TestNestmateMembership$CallerSelfHost (loader: 'app'): current type is not listed as a nest member"; try { CallerSelfHost.putFieldTarget(); - throw new Error("Missing IncompatibleClassChangeError: " + msg); + throw new Error("Missing IllegalAccessError: " + msg); } - catch (IncompatibleClassChangeError expected) { + catch (IllegalAccessError expected) { check_expected(expected, msg); } - msg = "Type TestNestmateMembership$CallerSelfHost (loader: 'app') is not a nest member" + - " of TestNestmateMembership$CallerSelfHost (loader: 'app'): current type is not listed as a nest member"; try { CallerSelfHost.putFieldTargetSelfHost(); - throw new Error("Missing IncompatibleClassChangeError: " + msg); + throw new Error("Missing IllegalAccessError: " + msg); } - catch (IncompatibleClassChangeError expected) { + catch (IllegalAccessError expected) { check_expected(expected, msg); } } static void test_MissingHostPutField() throws Throwable { System.out.println("Testing for nest-host class that does not exist"); - String msg = "Unable to load nest-host class (NoTargetMissingHost) of " + - "TestNestmateMembership$TargetMissingHost"; - String cause_msg = "NoTargetMissingHost"; + String msg = "Nest host resolution of TestNestmateMembership$TargetMissingHost with " + + "host NoTargetMissingHost failed: java.lang.NoClassDefFoundError: NoTargetMissingHost"; try { Caller.putFieldTargetMissingHost(); - throw new Error("Missing NoClassDefFoundError: " + msg); + throw new Error("Missing IllegalAccessError: " + msg); } - catch (NoClassDefFoundError expected) { - check_expected(expected, msg, cause_msg); + catch (IllegalAccessError expected) { + check_expected(expected, msg); } + msg = "class TestNestmateMembership$Caller cannot access a member of class " + + "TestNestmateMembership$TargetMissingHost with modifiers \"private static\""; try { Caller.putFieldTargetMissingHostReflectively(); - throw new Error("Missing NoClassDefFoundError: " + msg); + throw new Error("Missing IllegalAccessException: " + msg); } - catch (NoClassDefFoundError expected) { - check_expected(expected, msg, cause_msg); + catch (IllegalAccessException expected) { + check_expected(expected, msg); } + msg = "member is private: TestNestmateMembership$TargetMissingHost.f/int/putStatic, " + + "from class TestNestmateMembership$Caller"; try { Caller.putFieldTargetMissingHostMH(); - throw new Error("Missing NoClassDefFoundError: " + msg); + throw new Error("Missing IllegalAccessException: " + msg); } - catch (NoClassDefFoundError expected) { - check_expected(expected, msg, cause_msg); + catch (IllegalAccessException expected) { + check_expected(expected, msg); } - - msg = "Unable to load nest-host class (NoCallerMissingHost) of " + - "TestNestmateMembership$CallerMissingHost"; - cause_msg = "NoCallerMissingHost"; + msg = "Nest host resolution of TestNestmateMembership$CallerMissingHost with host " + + "NoCallerMissingHost failed: java.lang.NoClassDefFoundError: NoCallerMissingHost"; try { CallerMissingHost.putFieldTarget(); - throw new Error("Missing NoClassDefFoundError: " + msg); + throw new Error("Missing IllegalAccessError: " + msg); } - catch (NoClassDefFoundError expected) { - check_expected(expected, msg, cause_msg); + catch (IllegalAccessError expected) { + check_expected(expected, msg); } - msg = "Unable to load nest-host class (NoCallerMissingHost) of "+ - "TestNestmateMembership$CallerMissingHost"; - cause_msg = "NoCallerMissingHost"; try { CallerMissingHost.putFieldTargetMissingHost(); - throw new Error("Missing NoClassDefFoundError: " + msg); + throw new Error("Missing IllegalAccessError: " + msg); } - catch (NoClassDefFoundError expected) { - check_expected(expected, msg, cause_msg); + catch (IllegalAccessError expected) { + check_expected(expected, msg); } } static void test_NotInstanceHostPutField() throws Throwable { System.out.println("Testing for nest-host class that is not an instance class"); String msg = "Type TestNestmateMembership$TargetNotInstanceHost (loader: 'app') is not a "+ - "nest member of [LInvalidNestHost; (loader: 'app'): current type is not listed as a nest member"; + "nest member of type [LInvalidNestHost; (loader: 'app'): host is not an instance class"; try { Caller.putFieldTargetNotInstanceHost(); - throw new Error("Missing IncompatibleClassChangeError: " + msg); + throw new Error("Missing IllegalAccessError: " + msg); } - catch (IncompatibleClassChangeError expected) { + catch (IllegalAccessError expected) { check_expected(expected, msg); } + msg = "class TestNestmateMembership$Caller cannot access a member of class " + + "TestNestmateMembership$TargetNotInstanceHost with modifiers \"private static\""; try { Caller.putFieldTargetNotInstanceHostReflectively(); - throw new Error("Missing IncompatibleClassChangeError: " + msg); + throw new Error("Missing IllegalAccessException: " + msg); } - catch (IncompatibleClassChangeError expected) { + catch (IllegalAccessException expected) { check_expected(expected, msg); } + msg = "member is private: TestNestmateMembership$TargetNotInstanceHost.f/int/putStatic, " + + "from class TestNestmateMembership$Caller"; try { Caller.putFieldTargetNotInstanceHostMH(); - throw new Error("Missing IncompatibleClassChangeError: " + msg); + throw new Error("Missing IllegalAccessException: " + msg); } - catch (IncompatibleClassChangeError expected) { + catch (IllegalAccessException expected) { check_expected(expected, msg); } msg = "Type TestNestmateMembership$CallerNotInstanceHost (loader: 'app') is not a "+ - "nest member of [LInvalidNestHost; (loader: 'app'): current type is not listed as a nest member"; + "nest member of type [LInvalidNestHost; (loader: 'app'): host is not an instance class"; try { CallerNotInstanceHost.putFieldTarget(); - throw new Error("Missing IncompatibleClassChangeError: " + msg); + throw new Error("Missing IllegalAccessError: " + msg); } - catch (IncompatibleClassChangeError expected) { + catch (IllegalAccessError expected) { check_expected(expected, msg); } - msg = "Type TestNestmateMembership$CallerNotInstanceHost (loader: 'app') is not a "+ - "nest member of [LInvalidNestHost; (loader: 'app'): current type is not listed as a nest member"; try { CallerNotInstanceHost.putFieldTargetNotInstanceHost(); - throw new Error("Missing IncompatibleClassChangeError: " + msg); + throw new Error("Missing IllegalAccessError: " + msg); } - catch (IncompatibleClassChangeError expected) { + catch (IllegalAccessError expected) { check_expected(expected, msg); } } @@ -1676,45 +1679,46 @@ static void test_NotOurHostPutField() throws Throwable { System.out.println("Testing for nest-host class that does not list us in its nest"); String msg = "Type TestNestmateMembership$TargetNotOurHost (loader: 'app') is not a nest member" + - " of InvalidNestHost (loader: 'app'): current type is not listed as a nest member"; + " of type InvalidNestHost (loader: 'app'): current type is not listed as a nest member"; try { Caller.putFieldTargetNotOurHost(); - throw new Error("Missing IncompatibleClassChangeError: " + msg); + throw new Error("Missing IllegalAccessError: " + msg); } - catch (IncompatibleClassChangeError expected) { + catch (IllegalAccessError expected) { check_expected(expected, msg); } + msg = "class TestNestmateMembership$Caller cannot access a member of class " + + "TestNestmateMembership$TargetNotOurHost with modifiers \"private static\""; try { Caller.putFieldTargetNotOurHostReflectively(); - throw new Error("Missing IncompatibleClassChangeError: " + msg); + throw new Error("Missing IllegalAccessException: " + msg); } - catch (IncompatibleClassChangeError expected) { + catch (IllegalAccessException expected) { check_expected(expected, msg); } + msg = "member is private: TestNestmateMembership$TargetNotOurHost.f/int/putStatic, " + + "from class TestNestmateMembership$Caller"; try { Caller.putFieldTargetNotOurHostMH(); - throw new Error("Missing IncompatibleClassChangeError: " + msg); + throw new Error("Missing IllegalAccessException: " + msg); } - catch (IncompatibleClassChangeError expected) { + catch (IllegalAccessException expected) { check_expected(expected, msg); } - msg = "Type TestNestmateMembership$CallerNotOurHost (loader: 'app') is not a nest member" + - " of InvalidNestHost (loader: 'app'): current type is not listed as a nest member"; + " of type InvalidNestHost (loader: 'app'): current type is not listed as a nest member"; try { CallerNotOurHost.putFieldTarget(); - throw new Error("Missing IncompatibleClassChangeError: " + msg); + throw new Error("Missing IllegalAccessError: " + msg); } - catch (IncompatibleClassChangeError expected) { + catch (IllegalAccessError expected) { check_expected(expected, msg); } - msg = "Type TestNestmateMembership$CallerNotOurHost (loader: 'app') is not a nest member" + - " of InvalidNestHost (loader: 'app'): current type is not listed as a nest member"; try { CallerNotOurHost.putFieldTargetNotOurHost(); - throw new Error("Missing IncompatibleClassChangeError: " + msg); + throw new Error("Missing IllegalAccessError: " + msg); } - catch (IncompatibleClassChangeError expected) { + catch (IllegalAccessError expected) { check_expected(expected, msg); } } @@ -1722,19 +1726,19 @@ static void test_WrongPackageHostPutField() { System.out.println("Testing for nest-host and nest-member in different packages"); String msg = "Type P2.PackagedNestHost2$Member (loader: 'app') is not a nest member of " + - "P1.PackagedNestHost (loader: 'app'): types are in different packages"; + "type P1.PackagedNestHost (loader: 'app'): types are in different packages"; try { P1.PackagedNestHost.doPutField(); - throw new Error("Missing IncompatibleClassChangeError: " + msg); + throw new Error("Missing IllegalAccessError: " + msg); } - catch (IncompatibleClassChangeError expected) { + catch (IllegalAccessError expected) { check_expected(expected, msg); } try { P2.PackagedNestHost2.Member.doPutField(); - throw new Error("Missing IncompatibleClassChangeError: " + msg); + throw new Error("Missing IllegalAccessError: " + msg); } - catch (IncompatibleClassChangeError expected) { + catch (IllegalAccessError expected) { check_expected(expected, msg); } } @@ -1745,31 +1749,8 @@ if (!expected.getMessage().contains(msg)) { throw new Error("Wrong " + expected.getClass().getSimpleName() +": \"" + expected.getMessage() + "\" does not contain \"" + - msg + "\""); + msg + "\"", expected); } System.out.println("OK - got expected exception: " + expected); } - - static void check_expected(Throwable expected, String msg, String cause_msg) { - if (!expected.getMessage().contains(msg)) { - throw new Error("Wrong " + expected.getClass().getSimpleName() +": \"" + - expected.getMessage() + "\" does not contain \"" + - msg + "\""); - } - Throwable cause = expected.getCause(); - if (cause instanceof NoClassDefFoundError) { - if (!cause.getMessage().contains(cause_msg)) { - throw new Error(expected.getClass().getSimpleName() + - " has wrong cause " + cause.getClass().getSimpleName() +": \"" + - cause.getMessage() + "\" does not contain \"" + - cause_msg + "\""); - } - } - else throw new Error(expected.getClass().getSimpleName() + - " has wrong cause " + cause.getClass().getSimpleName()); - - System.out.println("OK - got expected exception: " + expected + - " with cause " + cause); - } - } --- old/test/hotspot/jtreg/runtime/Nestmates/privateMethods/TestInvokeErrors.java 2020-03-08 19:03:45.644138023 -0400 +++ new/test/hotspot/jtreg/runtime/Nestmates/privateMethods/TestInvokeErrors.java 2020-03-08 19:03:44.504125376 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -74,8 +74,12 @@ m.priv_invoke(); throw new Error("Unexpected success invoking MissingNestHost.priv_invoke"); } - catch (NoClassDefFoundError ncdfe) { - System.out.println("Got expected exception:" + ncdfe); + catch (IllegalAccessError iae) { + if (iae.getMessage().contains("java.lang.NoClassDefFoundError: NoSuchClass")) { + System.out.println("Got expected exception:" + iae); + } else { + throw new Error("Unexpected exception", iae); + } } } } @@ -105,11 +109,11 @@ try { Helper.doTest(); } - catch (NoClassDefFoundError ncdfe) { + catch (IllegalAccessError iae) { if (verifying) - System.out.println("Got expected exception:" + ncdfe); + System.out.println("Got expected exception:" + iae); else - throw new Error("Unexpected error loading Helper class with verification disabled"); + throw new Error("Unexpected error loading Helper class with verification disabled", iae); } } } --- old/test/jdk/java/lang/invoke/defineHiddenClass/BasicTest.java 2020-03-08 19:03:51.233200025 -0400 +++ new/test/jdk/java/lang/invoke/defineHiddenClass/BasicTest.java 2020-03-08 19:03:50.091187357 -0400 @@ -285,18 +285,15 @@ public void hasInnerClassesOrEnclosingMethodAttribute(String className, String badDeclaringClassName) throws Throwable { byte[] bytes = Files.readAllBytes(CLASSES_10_DIR.resolve(className + ".class")); Class hc = lookup().defineHiddenClass(bytes, false).lookupClass(); - hiddenClassWithBadAttribute(hc, badDeclaringClassName, null); + hiddenClassWithBadAttribute(hc, badDeclaringClassName); } - private static final String BAD_NEST_HOST_CLASS_ERROR = "Unable to load nest-host class (Outer) of Outer$Inner/"; - // define a hidden class with static nest membership - // it fails when it attempts to validate the nest membership @Test public void hasStaticNestHost() throws Exception { byte[] bytes = Files.readAllBytes(CLASSES_DIR.resolve("Outer$Inner.class")); Class hc = lookup().defineHiddenClass(bytes, false).lookupClass(); - hiddenClassWithBadAttribute(hc, "Outer", BAD_NEST_HOST_CLASS_ERROR); + hiddenClassWithBadAttribute(hc, "Outer"); } @Test @@ -305,19 +302,12 @@ Class hc = lookup().defineHiddenClass(bytes, false).lookupClass(); assertHiddenClass(hc); assertTrue(hc.getNestHost() == hc); - try { - // fail to validate the static nest membership - hc.getNestMembers(); - assertTrue(false); - } catch (NoClassDefFoundError e) { - if (!e.getMessage().equals("Outer$Inner")) { - throw e; - } - } + Class[] members = hc.getNestMembers(); + assertTrue(members.length == 1 && members[0] == hc); } // a hidden class with bad InnerClasses or EnclosingMethod attribute - private void hiddenClassWithBadAttribute(Class hc, String badDeclaringClassName, String badNestMembersError) { + private void hiddenClassWithBadAttribute(Class hc, String badDeclaringClassName) { assertTrue(hc.isHiddenClass()); assertTrue(hc.getCanonicalName() == null); assertTrue(hc.getName().contains("/")); @@ -333,17 +323,11 @@ declaringClassNotFound(hc, badDeclaringClassName); } - // validation of nest membership may fail + // validation of nest membership assertTrue(hc.getNestHost() == hc); - try { - // validate the static nest membership - hc.getNestMembers(); - assertTrue(badNestMembersError == null); - } catch (NoClassDefFoundError e) { - if (!e.getMessage().startsWith(badNestMembersError)) { - throw e; - } - } + // validate the static nest membership + Class[] members = hc.getNestMembers(); + assertTrue(members.length == 1 && members[0] == hc); } // Class::getSimpleName, Class::isMemberClass --- old/test/jdk/java/lang/reflect/Nestmates/TestReflectionAPI.java 2020-03-08 19:03:56.840262228 -0400 +++ new/test/jdk/java/lang/reflect/Nestmates/TestReflectionAPI.java 2020-03-08 19:03:55.696249536 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -176,7 +176,7 @@ HostWithDuplicateMembers.Member2.class }, true); - // Hosts with "bad" members + // Hosts with only "bad" members Class[] bad = { HostOfMemberNoHost.class, HostOfMemberMissingHost.class, @@ -184,44 +184,7 @@ HostOfMemberNotInstanceHost.class, HostOfMemberMalformedHost.class, }; - Class[] exceptions = { - IncompatibleClassChangeError.class, - NoClassDefFoundError.class, - IncompatibleClassChangeError.class, - IncompatibleClassChangeError.class, - ClassFormatError.class, - }; - String[] messages = { - "Nest member HostOfMemberNoHost$MemberNoHost in HostOfMemberNoHost " + - "declares a different nest host of HostOfMemberNoHost$MemberNoHost", - "Unable to load nest-host class (NestHost) of " + - "HostOfMemberMissingHost$MemberMissingHost", - "Type HostOfMemberNotOurHost$MemberNotOurHost (loader: 'app') is not a nest member " + - "of InvalidNestHost (loader: 'app'): current type is not listed as a nest member", - "Type HostOfMemberNotInstanceHost$MemberNotInstanceHost (loader: 'app') is not a nest " + - "member of [LInvalidNestHost; (loader: 'app'): current type is not listed as a nest member", - "Incompatible magic value 3735928559 in class file MalformedHost", - }; - for (int i = 0; i < bad.length; i++) { - try { - bad[i].getNestMembers(); - throw new Error("getNestMembers() succeeded for class " + - bad[i].getName()); - } catch (LinkageError e) { - checkException(e, messages[i], exceptions[i]); - } - } - } - - static void checkException(Throwable actual, String msg, Class expected) { - if (!actual.getClass().equals(expected)) - throw new Error("Unexpected exception: got " + actual.getClass().getName() - + " but expected " + expected.getName()); - if (!actual.getMessage().contains(msg)) - throw new Error("Wrong " + actual.getClass().getSimpleName() +": \"" + - actual.getMessage() + "\" does not contain \"" + - msg + "\""); - System.out.println("OK - got expected exception: " + actual); + checkSingletonNests(bad); } static void checkHost(Class target, Class expected) {