@@ -212,31 +212,45 @@ bool InstanceKlass::has_nest_member(JavaThread* current, InstanceKlass* k) const
212212 return false ;
213213}
214214
215- // Called to verify that k is a permitted subclass of this class
216- bool InstanceKlass::has_as_permitted_subclass (const InstanceKlass* k) const {
215+ // Called to verify that k is a permitted subclass of this class.
216+ // The incoming stringStream is used to format the messages for error logging and for the caller
217+ // to use for exception throwing.
218+ bool InstanceKlass::has_as_permitted_subclass (const InstanceKlass* k, stringStream& ss) const {
217219 Thread* current = Thread::current ();
218220 assert (k != nullptr , " sanity check" );
219221 assert (_permitted_subclasses != nullptr && _permitted_subclasses != Universe::the_empty_short_array (),
220222 " unexpected empty _permitted_subclasses array" );
221223
222224 if (log_is_enabled (Trace, class , sealed)) {
223225 ResourceMark rm (current);
224- log_trace (class , sealed)(" Checking for permitted subclass of %s in %s" ,
226+ log_trace (class , sealed)(" Checking for permitted subclass %s in %s" ,
225227 k->external_name (), this ->external_name ());
226228 }
227229
228230 // Check that the class and its super are in the same module.
229231 if (k->module () != this ->module ()) {
230- ResourceMark rm (current);
231- log_trace (class , sealed)(" Check failed for same module of permitted subclass %s and sealed class %s" ,
232- k->external_name (), this ->external_name ());
232+ ss.print (" Failed same module check: subclass %s is in module '%s' with loader %s, "
233+ " and sealed class %s is in module '%s' with loader %s" ,
234+ k->external_name (),
235+ k->module ()->name_as_C_string (),
236+ k->module ()->loader_data ()->loader_name_and_id (),
237+ this ->external_name (),
238+ this ->module ()->name_as_C_string (),
239+ this ->module ()->loader_data ()->loader_name_and_id ());
240+ log_trace (class , sealed)(" - %s" , ss.as_string ());
233241 return false ;
234242 }
235243
236244 if (!k->is_public () && !is_same_class_package (k)) {
237- ResourceMark rm (current);
238- log_trace (class , sealed)(" Check failed, subclass %s not public and not in the same package as sealed class %s" ,
239- k->external_name (), this ->external_name ());
245+ ss.print (" Failed same package check: non-public subclass %s is in package '%s' with classloader %s, "
246+ " and sealed class %s is in package '%s' with classloader %s" ,
247+ k->external_name (),
248+ k->package () != nullptr ? k->package ()->name ()->as_C_string () : " unnamed" ,
249+ k->module ()->loader_data ()->loader_name_and_id (),
250+ this ->external_name (),
251+ this ->package () != nullptr ? this ->package ()->name ()->as_C_string () : " unnamed" ,
252+ this ->module ()->loader_data ()->loader_name_and_id ());
253+ log_trace (class , sealed)(" - %s" , ss.as_string ());
240254 return false ;
241255 }
242256
@@ -248,7 +262,10 @@ bool InstanceKlass::has_as_permitted_subclass(const InstanceKlass* k) const {
248262 return true ;
249263 }
250264 }
251- log_trace (class , sealed)(" - class is NOT a permitted subclass!" );
265+
266+ ss.print (" Failed listed permitted subclass check: class %s is not a permitted subclass of %s" ,
267+ k->external_name (), this ->external_name ());
268+ log_trace (class , sealed)(" - %s" , ss.as_string ());
252269 return false ;
253270}
254271
0 commit comments