--- old/src/hotspot/share/classfile/javaClasses.cpp 2018-07-12 14:54:50.126293491 -0400 +++ new/src/hotspot/share/classfile/javaClasses.cpp 2018-07-12 14:54:48.403508294 -0400 @@ -4129,37 +4129,6 @@ return loader->obj_field(unnamedModule_offset); } -// Caller needs ResourceMark. -const char* java_lang_ClassLoader::describe_external(const oop loader) { - ClassLoaderData *cld = ClassLoaderData::class_loader_data(loader); - const char* name = cld->loader_name_and_id(); - - // bootstrap loader - if (loader == NULL) { - return name; - } - - bool well_known_loader = SystemDictionary::is_system_class_loader(loader) || - SystemDictionary::is_platform_class_loader(loader); - - stringStream ss; - ss.print("%s (instance of %s", name, loader->klass()->external_name()); - if (!well_known_loader) { - oop pl = java_lang_ClassLoader::parent(loader); - ClassLoaderData *pl_cld = ClassLoaderData::class_loader_data(pl); - const char* parentName = pl_cld->loader_name_and_id(); - if (pl != NULL) { - ss.print(", child of %s %s", parentName, pl->klass()->external_name()); - } else { - // bootstrap loader - ss.print(", child of %s", parentName); - } - } - ss.print(")"); - - return ss.as_string(); -} - // Support for java_lang_System // #define SYSTEM_FIELDS_DO(macro) \ --- old/src/hotspot/share/classfile/javaClasses.hpp 2018-07-12 14:55:02.444697909 -0400 +++ new/src/hotspot/share/classfile/javaClasses.hpp 2018-07-12 14:55:00.768368462 -0400 @@ -1310,12 +1310,6 @@ // Debugging friend class JavaClasses; friend class ClassFileParser; // access to number_of_fake_fields - - // Describe ClassLoader for exceptions, tracing ... - // Prints "" (instance of , child of "" ). - // If a classloader has no name, it prints instead. The output - // for well known loaders (system/platform) is abbreviated. - static const char* describe_external(const oop loader); }; --- old/src/hotspot/share/classfile/systemDictionary.cpp 2018-07-12 14:55:13.859107846 -0400 +++ new/src/hotspot/share/classfile/systemDictionary.cpp 2018-07-12 14:55:12.246306225 -0400 @@ -2084,9 +2084,9 @@ assert(check->is_instance_klass(), "noninstance in systemdictionary"); if ((defining == true) || (k != check)) { throwException = true; - ss.print("loader %s", java_lang_ClassLoader::describe_external(class_loader())); - ss.print(" attempted duplicate %s definition for %s.", - k->external_kind(), k->external_name()); + ss.print("loader %s", loader_data->loader_name_and_id()); + ss.print(" attempted duplicate %s definition for %s. (%s)", + k->external_kind(), k->external_name(), k->class_in_module_of_loader(false, true)); } else { return; } @@ -2100,15 +2100,17 @@ if (throwException == false) { if (constraints()->check_or_update(k, class_loader, name) == false) { throwException = true; - ss.print("loader constraint violation: loader %s", - java_lang_ClassLoader::describe_external(class_loader())); + ss.print("loader constraint violation: loader %s", loader_data->loader_name_and_id()); ss.print(" wants to load %s %s.", k->external_kind(), k->external_name()); Klass *existing_klass = constraints()->find_constrained_klass(name, class_loader); if (existing_klass->class_loader() != class_loader()) { - ss.print(" A different %s with the same name was previously loaded by %s.", + ss.print(" A different %s with the same name was previously loaded by %s. (%s)", existing_klass->external_kind(), - java_lang_ClassLoader::describe_external(existing_klass->class_loader())); + existing_klass->class_loader_data()->loader_name_and_id(), + existing_klass->class_in_module_of_loader(false, true)); + } else { + ss.print(" (%s)", k->class_in_module_of_loader(false, true)); } } } --- old/src/hotspot/share/interpreter/linkResolver.cpp 2018-07-12 14:55:26.141461362 -0400 +++ new/src/hotspot/share/interpreter/linkResolver.cpp 2018-07-12 14:55:24.583085163 -0400 @@ -669,23 +669,28 @@ SystemDictionary::check_signature_loaders(link_info.signature(), current_loader, resolved_loader, true, CHECK); if (failed_type_symbol != NULL) { - const char* msg = "loader constraint violation: when resolving %s" - " \"%s\" the class loader %s of the current class, %s," - " and the class loader %s for the method's defining class, %s, have" - " different Class objects for the type %s used in the signature"; - char* sig = link_info.method_string(); - const char* loader1_name = java_lang_ClassLoader::describe_external(current_loader()); - char* current = link_info.current_klass()->name()->as_C_string(); - const char* loader2_name = java_lang_ClassLoader::describe_external(resolved_loader()); - char* target = resolved_method->method_holder()->name()->as_C_string(); - char* failed_type_name = failed_type_symbol->as_C_string(); - size_t buflen = strlen(msg) + strlen(sig) + strlen(loader1_name) + - strlen(current) + strlen(loader2_name) + strlen(target) + - strlen(failed_type_name) + strlen(method_type) + 1; - char* buf = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, buflen); - jio_snprintf(buf, buflen, msg, method_type, sig, loader1_name, current, loader2_name, - target, failed_type_name); - THROW_MSG(vmSymbols::java_lang_LinkageError(), buf); + Klass* current_class = link_info.current_klass(); + ClassLoaderData* current_loader_data = current_class->class_loader_data(); + assert(current_loader_data != NULL, "current class has no class loader data"); + Klass* resolved_method_class = resolved_method->method_holder(); + ClassLoaderData* target_loader_data = resolved_method_class->class_loader_data(); + assert(target_loader_data != NULL, "resolved method's class has no class loader data"); + + stringStream ss; + ss.print("loader constraint violation: when resolving %s" + " \"%s\" the class loader %s of the current class, %s," + " and the class loader %s for the method's defining class, %s, have" + " different Class objects for the type %s used in the signature (%s; %s)", + method_type, + link_info.method_string(), + current_loader_data->loader_name_and_id(), + current_class->name()->as_C_string(), + target_loader_data->loader_name_and_id(), + resolved_method_class->name()->as_C_string(), + failed_type_symbol->as_C_string(), + current_class->class_in_module_of_loader(false, true), + resolved_method_class->class_in_module_of_loader(false, true)); + THROW_MSG(vmSymbols::java_lang_LinkageError(), ss.as_string()); } } @@ -702,23 +707,23 @@ false, CHECK); if (failed_type_symbol != NULL) { - const char* msg = "loader constraint violation: when resolving field" - " \"%s\" of type %s, the class loader %s of the current class, " - "%s, and the class loader %s for the field's defining " - "type, %s, have different Class objects for type %s"; - const char* field_name = field->as_C_string(); - const char* loader1_name = java_lang_ClassLoader::describe_external(ref_loader()); - const char* sel = sel_klass->external_name(); - const char* loader2_name = java_lang_ClassLoader::describe_external(sel_loader()); + stringStream ss; const char* failed_type_name = failed_type_symbol->as_klass_external_name(); - const char* curr_klass_name = current_klass->external_name(); - size_t buflen = strlen(msg) + strlen(field_name) + 2 * strlen(failed_type_name) + - strlen(loader1_name) + strlen(curr_klass_name) + - strlen(loader2_name) + strlen(sel) + 1; - char* buf = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, buflen); - jio_snprintf(buf, buflen, msg, field_name, failed_type_name, loader1_name, - curr_klass_name, loader2_name, sel, failed_type_name); - THROW_MSG(vmSymbols::java_lang_LinkageError(), buf); + + ss.print("loader constraint violation: when resolving field" + " \"%s\" of type %s, the class loader %s of the current class, " + "%s, and the class loader %s for the field's defining " + "type, %s, have different Class objects for type %s (%s; %s)", + field->as_C_string(), + failed_type_name, + current_klass->class_loader_data()->loader_name_and_id(), + current_klass->external_name(), + sel_klass->class_loader_data()->loader_name_and_id(), + sel_klass->external_name(), + failed_type_name, + current_klass->class_in_module_of_loader(false, true), + sel_klass->class_in_module_of_loader(false, true)); + THROW_MSG(vmSymbols::java_lang_LinkageError(), ss.as_string()); } } --- old/src/hotspot/share/oops/klassVtable.cpp 2018-07-12 14:55:38.727608235 -0400 +++ new/src/hotspot/share/oops/klassVtable.cpp 2018-07-12 14:55:36.882378226 -0400 @@ -506,24 +506,21 @@ super_loader, true, CHECK_(false)); if (failed_type_symbol != NULL) { - const char* msg = "loader constraint violation for class %s: when selecting " - "overriding method %s the class loader %s of the " - "selected method's type %s, and the class loader %s for its super " - "type %s have different Class objects for the type %s used in the signature"; - const char* curr_class = klass->external_name(); - const char* method = target_method()->name_and_sig_as_C_string(); - const char* loader1 = java_lang_ClassLoader::describe_external(target_loader()); - const char* sel_class = target_klass->external_name(); - const char* loader2 = java_lang_ClassLoader::describe_external(super_loader()); - const char* super_class = super_klass->external_name(); - const char* failed_type_name = failed_type_symbol->as_klass_external_name(); - size_t buflen = strlen(msg) + strlen(curr_class) + strlen(method) + - strlen(loader1) + strlen(sel_class) + strlen(loader2) + - strlen(super_class) + strlen(failed_type_name); - char* buf = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, buflen); - jio_snprintf(buf, buflen, msg, curr_class, method, loader1, sel_class, loader2, - super_class, failed_type_name); - THROW_MSG_(vmSymbols::java_lang_LinkageError(), buf, false); + stringStream ss; + ss.print("loader constraint violation for class %s: when selecting " + "overriding method %s the class loader %s of the " + "selected method's type %s, and the class loader %s for its super " + "type %s have different Class objects for the type %s used in the signature (%s; %s)", + klass->external_name(), + target_method()->name_and_sig_as_C_string(), + target_klass->class_loader_data()->loader_name_and_id(), + target_klass->external_name(), + super_klass->class_loader_data()->loader_name_and_id(), + super_klass->external_name(), + failed_type_symbol->as_klass_external_name(), + target_klass->class_in_module_of_loader(false, true), + super_klass->class_in_module_of_loader(false, true)); + THROW_MSG_(vmSymbols::java_lang_LinkageError(), ss.as_string(), false); } } } @@ -1241,25 +1238,22 @@ interface_loader, true, CHECK); if (failed_type_symbol != NULL) { - const char* msg = "loader constraint violation in interface itable" - " initialization for class %s: when selecting method %s the" - " class loader %s for super interface %s, and the class" - " loader %s of the selected method's type, %s have" - " different Class objects for the type %s used in the signature"; - const char* current = _klass->external_name(); - const char* sig = m->name_and_sig_as_C_string(); - const char* loader1 = java_lang_ClassLoader::describe_external(interface_loader()); - const char* iface = InstanceKlass::cast(interf)->external_name(); - const char* loader2 = java_lang_ClassLoader::describe_external(method_holder_loader()); - const char* mclass = target()->method_holder()->external_name(); - const char* failed_type_name = failed_type_symbol->as_klass_external_name(); - size_t buflen = strlen(msg) + strlen(current) + strlen(sig) + - strlen(loader1) + strlen(iface) + strlen(loader2) + strlen(mclass) + - strlen(failed_type_name); - char* buf = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, buflen); - jio_snprintf(buf, buflen, msg, current, sig, loader1, iface, - loader2, mclass, failed_type_name); - THROW_MSG(vmSymbols::java_lang_LinkageError(), buf); + stringStream ss; + ss.print("loader constraint violation in interface itable" + " initialization for class %s: when selecting method %s the" + " class loader %s for super interface %s, and the class" + " loader %s of the selected method's type, %s have" + " different Class objects for the type %s used in the signature (%s; %s)", + _klass->external_name(), + m->name_and_sig_as_C_string(), + interf->class_loader_data()->loader_name_and_id(), + interf->external_name(), + target()->method_holder()->class_loader_data()->loader_name_and_id(), + target()->method_holder()->external_name(), + failed_type_symbol->as_klass_external_name(), + interf->class_in_module_of_loader(false, true), + target()->method_holder()->class_in_module_of_loader(false, true)); + THROW_MSG(vmSymbols::java_lang_LinkageError(), ss.as_string()); } } } --- old/test/hotspot/jtreg/runtime/LoaderConstraints/differentLE/Test.java 2018-07-12 14:55:52.373710309 -0400 +++ new/test/hotspot/jtreg/runtime/LoaderConstraints/differentLE/Test.java 2018-07-12 14:55:50.901263295 -0400 @@ -78,11 +78,9 @@ // Break the expectedErrorMessage into 2 pieces since the loader name will include // its identity hash and can not be compared against. static String expectedErrorMessage_part1 = "loader constraint violation: loader PreemptingClassLoader @"; - static String expectedErrorMessage_part2 = " (instance of PreemptingClassLoader, " + - "child of 'app' jdk.internal.loader.ClassLoaders$AppClassLoader) wants to load " + - "class test.D_ambgs. A different class with the same name was previously loaded " + - "by 'app' (instance of jdk.internal.loader.ClassLoaders$AppClassLoader)."; - + static String expectedErrorMessage_part2 = " wants to load class test.D_ambgs. A different class " + + "with the same name was previously loaded by 'app'. " + + "(test.D_ambgs is in unnamed module of loader 'app')"; public static void test_access() throws Exception { try { // Make a Class 'D_ambgs' under the default loader. @@ -118,4 +116,3 @@ test_access(); } } - --- old/test/hotspot/jtreg/runtime/LoaderConstraints/duplicateLE/Test.java 2018-07-12 14:56:03.898158288 -0400 +++ new/test/hotspot/jtreg/runtime/LoaderConstraints/duplicateLE/Test.java 2018-07-12 14:56:02.380459381 -0400 @@ -40,26 +40,21 @@ // Break each expectedErrorMessage into 2 parts due to the class loader name containing // the unique @ identity hash which cannot be compared against. static String expectedErrorMessage1_part1 = "loader PreemptingClassLoader @"; - static String expectedErrorMessage1_part2 = - " (instance of PreemptingClassLoader, " + - "child of 'app' jdk.internal.loader.ClassLoaders$AppClassLoader) " + - "attempted duplicate class definition for test.Foo."; + static String expectedErrorMessage1_part2 = " attempted duplicate class definition for test.Foo. (test.Foo is in unnamed module of loader PreemptingClassLoader @"; + static String expectedErrorMessage1_part3 = ", parent loader 'app')"; // Check that all names have external formatting ('.' and not '/' in package names). // Check for name and parent of class loader. static String expectedErrorMessage2_part1 = "loader 'DuplicateLE_Test_Loader' @"; - static String expectedErrorMessage2_part2 = - " (instance of PreemptingClassLoader, " + - "child of 'app' jdk.internal.loader.ClassLoaders$AppClassLoader) " + - "attempted duplicate class definition for test.Foo."; + static String expectedErrorMessage2_part2 = " attempted duplicate class definition for test.Foo. (test.Foo is in unnamed module of loader 'DuplicateLE_Test_Loader' @"; + static String expectedErrorMessage2_part3 = ", parent loader 'app')"; // Check that all names have external formatting ('.' and not '/' in package names). // Check for name and parent of class loader. Type should be mentioned as 'interface'. static String expectedErrorMessage3_part1 = "loader 'DuplicateLE_Test_Loader_IF' @"; - static String expectedErrorMessage3_part2 = - " (instance of PreemptingClassLoader, " + - "child of 'app' jdk.internal.loader.ClassLoaders$AppClassLoader) " + - "attempted duplicate interface definition for test.J."; + static String expectedErrorMessage3_part2 = " attempted duplicate interface definition for test.J. (test.J is in unnamed module of loader 'DuplicateLE_Test_Loader_IF' @"; + static String expectedErrorMessage3_part3 = ", parent loader 'app')"; + // Test that the error message is correct when a loader constraint error is // detected during vtable creation. @@ -68,8 +63,11 @@ // overrides "J.m()LFoo;". But, Task's class Foo and super type J's class Foo // are different. So, a LinkageError exception should be thrown because the // loader constraint check will fail. - public static void test(String loaderName, String expectedErrorMessage_part1, - String expectedErrorMessage_part2, String testType) throws Exception { + public static void test(String loaderName, + String expectedErrorMessage_part1, + String expectedErrorMessage_part2, + String expectedErrorMessage_part3, + String testType) throws Exception { String[] classNames = {testType}; ClassLoader l = new PreemptingClassLoader(loaderName, classNames, false); l.loadClass(testType); @@ -79,7 +77,8 @@ } catch (LinkageError e) { String errorMsg = e.getMessage(); if (!errorMsg.contains(expectedErrorMessage_part1) || - !errorMsg.contains(expectedErrorMessage_part2)) { + !errorMsg.contains(expectedErrorMessage_part2) || + !errorMsg.contains(expectedErrorMessage_part3)) { System.out.println("Expected: " + expectedErrorMessage_part1 + "" + expectedErrorMessage_part2 + "\n" + "but got: " + errorMsg); throw new RuntimeException("Wrong LinkageError exception thrown: " + errorMsg); @@ -89,9 +88,11 @@ } public static void main(String args[]) throws Exception { - test(null, expectedErrorMessage1_part1, expectedErrorMessage1_part2, "test.Foo"); - test("DuplicateLE_Test_Loader", expectedErrorMessage2_part1, expectedErrorMessage2_part2, "test.Foo"); - test("DuplicateLE_Test_Loader_IF", expectedErrorMessage3_part1, expectedErrorMessage3_part2, "test.J"); + test(null, expectedErrorMessage1_part1, expectedErrorMessage1_part2, + expectedErrorMessage1_part3, "test.Foo"); + test("DuplicateLE_Test_Loader", expectedErrorMessage2_part1, expectedErrorMessage2_part2, + expectedErrorMessage2_part3, "test.Foo"); + test("DuplicateLE_Test_Loader_IF", expectedErrorMessage3_part1, expectedErrorMessage3_part2, + expectedErrorMessage3_part3, "test.J"); } } - --- old/test/hotspot/jtreg/runtime/LoaderConstraints/itableLdrConstraint/Test.java 2018-07-12 14:56:15.178758965 -0400 +++ new/test/hotspot/jtreg/runtime/LoaderConstraints/itableLdrConstraint/Test.java 2018-07-12 14:56:13.747005457 -0400 @@ -35,31 +35,25 @@ public class Test { - // Break expected error messages into 2 parts since the loader name includes its identity + // Break expected error messages into 3 parts since the loader name includes its identity // hash which is unique and can't be compared against. - static String expectedErrorMessage1_part1 = - "loader constraint violation in interface itable initialization for class test.C: " + - "when selecting method test.I.m()Ltest/Foo; " + - "the class loader PreemptingClassLoader @"; - static String expectedErrorMessage1_part2 = - " (instance of PreemptingClassLoader, " + - "child of 'app' jdk.internal.loader.ClassLoaders$AppClassLoader) " + - "for super interface test.I, and the class loader 'app' " + - "(instance of jdk.internal.loader.ClassLoaders$AppClassLoader) " + - "of the selected method's type, test.J have different Class objects " + - "for the type test.Foo used in the signature"; + static String expectedErrorMessage1_part1 = "loader constraint violation in interface itable initialization for " + + "class test.C: when selecting method test.I.m()Ltest/Foo; the class loader " + + "PreemptingClassLoader @"; + static String expectedErrorMessage1_part2 = " for super interface test.I, and the class loader 'app' of the " + + "selected method's type, test.J have different Class objects for the " + + "type test.Foo used in the signature (test.I is in unnamed module of loader " + + "PreemptingClassLoader @"; + static String expectedErrorMessage1_part3 = ", parent loader 'app'; test.J is in unnamed module of loader 'app')"; - static String expectedErrorMessage2_part1 = - "loader constraint violation in interface itable initialization for class test.C: " + - "when selecting method test.I.m()Ltest/Foo; " + - "the class loader 'ItableLdrCnstrnt_Test_Loader' @"; - static String expectedErrorMessage2_part2 = - " (instance of PreemptingClassLoader, " + - "child of 'app' jdk.internal.loader.ClassLoaders$AppClassLoader) " + - "for super interface test.I, and the class loader 'app' " + - "(instance of jdk.internal.loader.ClassLoaders$AppClassLoader) " + - "of the selected method's type, test.J have different Class objects " + - "for the type test.Foo used in the signature"; + static String expectedErrorMessage2_part1 = "loader constraint violation in interface itable initialization for " + + "class test.C: when selecting method test.I.m()Ltest/Foo; the class loader " + + "'ItableLdrCnstrnt_Test_Loader' @"; + static String expectedErrorMessage2_part2 = " for super interface test.I, and the class loader 'app' of the " + + "selected method's type, test.J have different Class objects for the " + + "type test.Foo used in the signature (test.I is in unnamed module of loader " + + "'ItableLdrCnstrnt_Test_Loader' @"; + static String expectedErrorMessage2_part3 = ", parent loader 'app'; test.J is in unnamed module of loader 'app')"; // Test that the error message is correct when a loader constraint error is // detected during itable creation. @@ -71,7 +65,8 @@ // exception should be thrown because the loader constraint check will fail. public static void test(String loaderName, String expectedErrorMessage_part1, - String expectedErrorMessage_part2) throws Exception { + String expectedErrorMessage_part2, + String expectedErrorMessage_part3) throws Exception { Class c = test.Foo.class; // Forces standard class loader to load Foo. String[] classNames = {"test.Task", "test.Foo", "test.C", "test.I"}; ClassLoader l = new PreemptingClassLoader(loaderName, classNames); @@ -82,7 +77,8 @@ } catch (LinkageError e) { String errorMsg = e.getMessage(); if (!errorMsg.contains(expectedErrorMessage_part1) || - !errorMsg.contains(expectedErrorMessage_part2)) { + !errorMsg.contains(expectedErrorMessage_part2) || + !errorMsg.contains(expectedErrorMessage_part3)) { System.out.println("Expected: " + expectedErrorMessage_part1 + "" + expectedErrorMessage_part2 + "\n" + "but got: " + errorMsg); throw new RuntimeException("Wrong LinkageError exception thrown: " + errorMsg); @@ -92,7 +88,7 @@ } public static void main(String... args) throws Exception { - test(null, expectedErrorMessage1_part1, expectedErrorMessage1_part2); - test("ItableLdrCnstrnt_Test_Loader", expectedErrorMessage2_part1, expectedErrorMessage2_part2); + test(null, expectedErrorMessage1_part1, expectedErrorMessage1_part2, expectedErrorMessage1_part3); + test("ItableLdrCnstrnt_Test_Loader", expectedErrorMessage2_part1, expectedErrorMessage2_part2, expectedErrorMessage2_part3); } } --- old/test/hotspot/jtreg/runtime/LoaderConstraints/vtableLdrConstraint/Test.java 2018-07-12 14:56:27.280893019 -0400 +++ new/test/hotspot/jtreg/runtime/LoaderConstraints/vtableLdrConstraint/Test.java 2018-07-12 14:56:25.853098114 -0400 @@ -35,31 +35,25 @@ public class Test { - // Break expected error messages into 2 parts since the loader name includes its identity + // Break expected error messages into 3 parts since the loader name includes its identity // hash which is unique and can't be compared against. - static String expectedErrorMessage1_part1 = - "loader constraint violation for class test.Task: " + - "when selecting overriding method test.Task.m()Ltest/Foo; " + - "the class loader PreemptingClassLoader @"; - static String expectedErrorMessage1_part2 = - " (instance of PreemptingClassLoader, " + - "child of 'app' jdk.internal.loader.ClassLoaders$AppClassLoader) " + - "of the selected method's type test.Task, " + - "and the class loader 'app' (instance of jdk.internal.loader.ClassLoaders$AppClassLoader) " + - "for its super type test.J " + - "have different Class objects for the type test.Foo used in the signature"; - - static String expectedErrorMessage2_part1 = - "loader constraint violation for class test.Task: " + - "when selecting overriding method test.Task.m()Ltest/Foo; " + - "the class loader 'VtableLdrCnstrnt_Test_Loader' @"; - static String expectedErrorMessage2_part2 = - " (instance of PreemptingClassLoader, " + - "child of 'app' jdk.internal.loader.ClassLoaders$AppClassLoader) " + - "of the selected method's type test.Task, " + - "and the class loader 'app' (instance of jdk.internal.loader.ClassLoaders$AppClassLoader) " + - "for its super type test.J " + - "have different Class objects for the type test.Foo used in the signature"; + static String expectedErrorMessage1_part1 = "loader constraint violation for class test.Task: when " + + "selecting overriding method test.Task.m()Ltest/Foo; the " + + "class loader PreemptingClassLoader @"; + static String expectedErrorMessage1_part2 = " of the selected method's type test.Task, and the class " + + "loader 'app' for its super type test.J have different Class objects " + + "for the type test.Foo used in the signature (test.Task is in unnamed " + + "module of loader PreemptingClassLoader @"; + static String expectedErrorMessage1_part3 = ", parent loader 'app'; test.J is in unnamed module of loader 'app')"; + + static String expectedErrorMessage2_part1 = "loader constraint violation for class test.Task: when " + + "selecting overriding method test.Task.m()Ltest/Foo; the " + + "class loader 'VtableLdrCnstrnt_Test_Loader' @"; + static String expectedErrorMessage2_part2 = " of the selected method's type test.Task, and the class " + + "loader 'app' for its super type test.J have different Class objects " + + "for the type test.Foo used in the signature (test.Task is in unnamed " + + "module of loader 'VtableLdrCnstrnt_Test_Loader' @"; + static String expectedErrorMessage2_part3 = ", parent loader 'app'; test.J is in unnamed module of loader 'app')"; // Test that the error message is correct when a loader constraint error is // detected during vtable creation. @@ -70,7 +64,8 @@ // loader constraint check will fail. public static void test(String loaderName, String expectedErrorMessage_part1, - String expectedErrorMessage_part2) throws Exception { + String expectedErrorMessage_part2, + String expectedErrorMessage_part3) throws Exception { Class c = test.Foo.class; // Forces standard class loader to load Foo. String[] classNames = {"test.Task", "test.Foo", "test.I"}; ClassLoader l = new PreemptingClassLoader(loaderName, classNames); @@ -81,7 +76,8 @@ } catch (LinkageError e) { String errorMsg = e.getMessage(); if (!errorMsg.contains(expectedErrorMessage_part1) || - !errorMsg.contains(expectedErrorMessage_part2)) { + !errorMsg.contains(expectedErrorMessage_part2) || + !errorMsg.contains(expectedErrorMessage_part3)) { System.out.println("Expected: " + expectedErrorMessage_part1 + "" + expectedErrorMessage_part2 + "\n" + "but got: " + errorMsg); throw new RuntimeException("Wrong LinkageError exception thrown: " + errorMsg); @@ -91,8 +87,9 @@ } public static void main(String args[]) throws Exception { - test(null, expectedErrorMessage1_part1, expectedErrorMessage1_part2); - test("VtableLdrCnstrnt_Test_Loader", expectedErrorMessage2_part1, expectedErrorMessage2_part2); + test(null, expectedErrorMessage1_part1, + expectedErrorMessage1_part2, expectedErrorMessage1_part3); + test("VtableLdrCnstrnt_Test_Loader", expectedErrorMessage2_part1, + expectedErrorMessage2_part2, expectedErrorMessage2_part3); } } -