8199852: Print more information about class loaders in LinkageErrors.
authorgoetz
Mon, 07 May 2018 11:38:21 +0200
changeset 50036 e0dbf14885b8
parent 50035 af1923174c9b
child 50037 92ec6aec6f06
8199852: Print more information about class loaders in LinkageErrors. Reviewed-by: dholmes, lfoltan, gtriantafill
src/hotspot/share/classfile/javaClasses.cpp
src/hotspot/share/classfile/javaClasses.hpp
src/hotspot/share/classfile/systemDictionary.cpp
src/hotspot/share/interpreter/linkResolver.cpp
src/hotspot/share/oops/klassVtable.cpp
test/hotspot/jtreg/runtime/LoaderConstraints/common/C.jasm
test/hotspot/jtreg/runtime/LoaderConstraints/common/Foo.java
test/hotspot/jtreg/runtime/LoaderConstraints/common/J.java
test/hotspot/jtreg/runtime/LoaderConstraints/common/PreemptingClassLoader.java
test/hotspot/jtreg/runtime/LoaderConstraints/differentLE/D_ambgs.jasm
test/hotspot/jtreg/runtime/LoaderConstraints/differentLE/Test.java
test/hotspot/jtreg/runtime/LoaderConstraints/differentLE/test/A.java
test/hotspot/jtreg/runtime/LoaderConstraints/differentLE/test/B.java
test/hotspot/jtreg/runtime/LoaderConstraints/differentLE/test/C.java
test/hotspot/jtreg/runtime/LoaderConstraints/differentLE/test/D_ambgs.java
test/hotspot/jtreg/runtime/LoaderConstraints/duplicateLE/Test.java
test/hotspot/jtreg/runtime/LoaderConstraints/itableICCE/I.java
test/hotspot/jtreg/runtime/LoaderConstraints/itableICCE/Task.java
test/hotspot/jtreg/runtime/LoaderConstraints/itableICCE/Test.java
test/hotspot/jtreg/runtime/LoaderConstraints/itableLdrConstraint/I.java
test/hotspot/jtreg/runtime/LoaderConstraints/itableLdrConstraint/Task.java
test/hotspot/jtreg/runtime/LoaderConstraints/itableLdrConstraint/Test.java
test/hotspot/jtreg/runtime/LoaderConstraints/vtableAME/I.java
test/hotspot/jtreg/runtime/LoaderConstraints/vtableAME/Task.java
test/hotspot/jtreg/runtime/LoaderConstraints/vtableAME/Test.java
test/hotspot/jtreg/runtime/LoaderConstraints/vtableLdrConstraint/I.java
test/hotspot/jtreg/runtime/LoaderConstraints/vtableLdrConstraint/Task.java
test/hotspot/jtreg/runtime/LoaderConstraints/vtableLdrConstraint/Test.java
--- a/src/hotspot/share/classfile/javaClasses.cpp	Mon May 07 14:42:10 2018 +0200
+++ b/src/hotspot/share/classfile/javaClasses.cpp	Mon May 07 11:38:21 2018 +0200
@@ -4134,6 +4134,48 @@
   return loader->obj_field(unnamedModule_offset);
 }
 
+// Caller needs ResourceMark.
+const char* java_lang_ClassLoader::describe_external(const oop loader) {
+  if (loader == NULL) {
+    return "<bootstrap>";
+  }
+
+  bool well_known_loader = SystemDictionary::is_system_class_loader(loader) ||
+                           SystemDictionary::is_platform_class_loader(loader);
+
+  const char* name = NULL;
+  oop nameOop = java_lang_ClassLoader::name(loader);
+  if (nameOop != NULL) {
+    name = java_lang_String::as_utf8_string(nameOop);
+  }
+  if (name == NULL) {
+    // Use placeholder for missing name to have fixed message format.
+    name = "<unnamed>";
+  }
+
+  stringStream ss;
+  ss.print("\"%s\" (instance of %s", name, loader->klass()->external_name());
+  if (!well_known_loader) {
+    const char* parentName = NULL;
+    oop pl = java_lang_ClassLoader::parent(loader);
+    if (pl != NULL) {
+      oop parentNameOop = java_lang_ClassLoader::name(pl);
+      if (parentNameOop != NULL) {
+        parentName = java_lang_String::as_utf8_string(parentNameOop);
+        if (parentName == NULL) {
+          parentName = "<unnamed>";
+        }
+      }
+      ss.print(", child of \"%s\" %s", parentName, pl->klass()->external_name());
+    } else {
+      ss.print(", child of <bootstrap>");
+    }
+  }
+  ss.print(")");
+
+  return ss.as_string();
+}
+
 // Support for java_lang_System
 //
 #define SYSTEM_FIELDS_DO(macro) \
--- a/src/hotspot/share/classfile/javaClasses.hpp	Mon May 07 14:42:10 2018 +0200
+++ b/src/hotspot/share/classfile/javaClasses.hpp	Mon May 07 11:38:21 2018 +0200
@@ -1321,6 +1321,12 @@
   // Debugging
   friend class JavaClasses;
   friend class ClassFileParser; // access to number_of_fake_fields
+
+  // Describe ClassLoader for exceptions, tracing ...
+  // Prints "<name>" (instance of <classname>, child of "<name>" <classname>).
+  // If a classloader has no name, it prints <unnamed> instead. The output
+  // for well known loaders (system/platform) is abbreviated.
+  static const char* describe_external(const oop loader);
 };
 
 
--- a/src/hotspot/share/classfile/systemDictionary.cpp	Mon May 07 14:42:10 2018 +0200
+++ b/src/hotspot/share/classfile/systemDictionary.cpp	Mon May 07 11:38:21 2018 +0200
@@ -2124,10 +2124,19 @@
 
 void SystemDictionary::check_constraints(unsigned int d_hash,
                                          InstanceKlass* k,
-                                         Handle class_loader, bool defining,
+                                         Handle class_loader,
+                                         bool defining,
                                          TRAPS) {
+  ResourceMark rm(THREAD);
+  stringStream ss;
+  bool throwException = false;
+
   const char *linkage_error1 = NULL;
   const char *linkage_error2 = NULL;
+  const char *linkage_error3 = "";
+  // Remember the loader of the similar class that is already loaded.
+  const char *existing_klass_loader_name = "";
+
   {
     Symbol*  name  = k->name();
     ClassLoaderData *loader_data = class_loader_data(class_loader);
@@ -2136,16 +2145,18 @@
 
     InstanceKlass* check = find_class(d_hash, name, loader_data->dictionary());
     if (check != NULL) {
-      // if different InstanceKlass - duplicate class definition,
-      // else - ok, class loaded by a different thread in parallel,
-      // we should only have found it if it was done loading and ok to use
-      // dictionary only holds instance classes, placeholders
-      // also holds array classes
+      // If different InstanceKlass - duplicate class definition,
+      // else - ok, class loaded by a different thread in parallel.
+      // We should only have found it if it was done loading and ok to use.
+      // The dictionary only holds instance classes, placeholders
+      // also hold array classes.
 
       assert(check->is_instance_klass(), "noninstance in systemdictionary");
       if ((defining == true) || (k != check)) {
-        linkage_error1 = "loader (instance of ";
-        linkage_error2 = "): attempted duplicate class definition for name: \"";
+        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());
       } else {
         return;
       }
@@ -2156,30 +2167,30 @@
     assert(ph_check == NULL || ph_check == name, "invalid symbol");
 #endif
 
-    if (linkage_error1 == NULL) {
+    if (throwException == false) {
       if (constraints()->check_or_update(k, class_loader, name) == false) {
-        linkage_error1 = "loader constraint violation: loader (instance of ";
-        linkage_error2 = ") previously initiated loading for a different type with name \"";
+        throwException = true;
+        ss.print("loader constraint violation: loader %s",
+                 java_lang_ClassLoader::describe_external(class_loader()));
+        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.",
+                   existing_klass->external_kind(),
+                   java_lang_ClassLoader::describe_external(existing_klass->class_loader()));
+        }
       }
     }
   }
 
   // Throw error now if needed (cannot throw while holding
   // SystemDictionary_lock because of rank ordering)
-
-  if (linkage_error1) {
-    ResourceMark rm(THREAD);
-    const char* class_loader_name = loader_name(class_loader());
-    char* type_name = k->name()->as_C_string();
-    size_t buflen = strlen(linkage_error1) + strlen(class_loader_name) +
-      strlen(linkage_error2) + strlen(type_name) + 2; // +2 for '"' and null byte.
-    char* buf = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, buflen);
-    jio_snprintf(buf, buflen, "%s%s%s%s\"", linkage_error1, class_loader_name, linkage_error2, type_name);
-    THROW_MSG(vmSymbols::java_lang_LinkageError(), buf);
+  if (throwException == true) {
+    THROW_MSG(vmSymbols::java_lang_LinkageError(), ss.as_string());
   }
 }
 
-
 // Update class loader data dictionary - done after check_constraint and add_to_hierachy
 // have been called.
 void SystemDictionary::update_dictionary(unsigned int d_hash,
--- a/src/hotspot/share/interpreter/linkResolver.cpp	Mon May 07 14:42:10 2018 +0200
+++ b/src/hotspot/share/interpreter/linkResolver.cpp	Mon May 07 11:38:21 2018 +0200
@@ -655,13 +655,13 @@
                                               resolved_loader, true, CHECK);
   if (failed_type_symbol != NULL) {
     const char* msg = "loader constraint violation: when resolving %s"
-      " \"%s\" the class loader (instance of %s) of the current class, %s,"
-      " and the class loader (instance of %s) for the method's defining class, %s, have"
+      " \"%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 = SystemDictionary::loader_name(current_loader());
+    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 = SystemDictionary::loader_name(resolved_loader());
+    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) +
@@ -688,13 +688,13 @@
                                               CHECK);
   if (failed_type_symbol != NULL) {
     const char* msg = "loader constraint violation: when resolving field"
-      " \"%s\" the class loader (instance of %s) of the referring class, "
-      "%s, and the class loader (instance of %s) for the field's resolved "
+      " \"%s\" the class loader %s of the referring class, "
+      "%s, and the class loader %s for the field's resolved "
       "type, %s, have different Class objects for that type";
     char* field_name = field->as_C_string();
-    const char* loader1_name = SystemDictionary::loader_name(ref_loader());
+    const char* loader1_name = java_lang_ClassLoader::describe_external(ref_loader());
     char* sel = sel_klass->name()->as_C_string();
-    const char* loader2_name = SystemDictionary::loader_name(sel_loader());
+    const char* loader2_name = java_lang_ClassLoader::describe_external(sel_loader());
     char* failed_type_name = failed_type_symbol->as_C_string();
     size_t buflen = strlen(msg) + strlen(field_name) + strlen(loader1_name) +
                     strlen(sel) + strlen(loader2_name) + strlen(failed_type_name) + 1;
--- a/src/hotspot/share/oops/klassVtable.cpp	Mon May 07 14:42:10 2018 +0200
+++ b/src/hotspot/share/oops/klassVtable.cpp	Mon May 07 11:38:21 2018 +0200
@@ -24,6 +24,7 @@
 
 #include "precompiled.hpp"
 #include "jvm.h"
+#include "classfile/javaClasses.hpp"
 #include "classfile/systemDictionary.hpp"
 #include "classfile/vmSymbols.hpp"
 #include "interpreter/linkResolver.hpp"
@@ -506,21 +507,21 @@
                                                         CHECK_(false));
             if (failed_type_symbol != NULL) {
               const char* msg = "loader constraint violation for class %s: when selecting "
-                "overriding method \"%s\" the class loader (instance of %s) of the "
-                "selected method's type %s, and the class loader (instance of %s) for its super "
+                "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";
-              char* curr_class = klass->name()->as_C_string();
-              char* sig = target_method()->name_and_sig_as_C_string();
-              const char* loader1 = SystemDictionary::loader_name(target_loader());
-              char* sel_class = target_klass->name()->as_C_string();
-              const char* loader2 = SystemDictionary::loader_name(super_loader());
-              char* super_class = super_klass->name()->as_C_string();
-              char* failed_type_name = failed_type_symbol->as_C_string();
-              size_t buflen = strlen(msg) + strlen(curr_class) + strlen(sig) +
+              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, sig, loader1, sel_class, loader2,
+              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);
             }
@@ -1236,17 +1237,17 @@
                                                       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 (instance of %s) for super interface %s, and the class"
-              " loader (instance of %s) of the selected method's type, %s have"
+              " 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";
-            char* current = _klass->name()->as_C_string();
-            char* sig = m->name_and_sig_as_C_string();
-            const char* loader1 = SystemDictionary::loader_name(interface_loader());
-            char* iface = InstanceKlass::cast(interf)->name()->as_C_string();
-            const char* loader2 = SystemDictionary::loader_name(method_holder_loader());
-            char* mclass = target()->method_holder()->name()->as_C_string();
-            char* failed_type_name = failed_type_symbol->as_C_string();
+            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);
--- a/test/hotspot/jtreg/runtime/LoaderConstraints/common/C.jasm	Mon May 07 14:42:10 2018 +0200
+++ b/test/hotspot/jtreg/runtime/LoaderConstraints/common/C.jasm	Mon May 07 11:38:21 2018 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2018, 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
@@ -26,6 +26,8 @@
 //   class C inherits unrelated defaults for m() from types I and J
 //   C is not abstract and does not override abstract method m() in I
 
+package test;
+
 super public class C implements I, J version 52:0 {
 
     public Method "<init>":"()V" stack 1 locals 1 {
--- a/test/hotspot/jtreg/runtime/LoaderConstraints/common/Foo.java	Mon May 07 14:42:10 2018 +0200
+++ b/test/hotspot/jtreg/runtime/LoaderConstraints/common/Foo.java	Mon May 07 11:38:21 2018 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2018, 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
@@ -21,4 +21,6 @@
  * questions.
  */
 
+package test;
+
 public class Foo {}
--- a/test/hotspot/jtreg/runtime/LoaderConstraints/common/J.java	Mon May 07 14:42:10 2018 +0200
+++ b/test/hotspot/jtreg/runtime/LoaderConstraints/common/J.java	Mon May 07 11:38:21 2018 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2018, 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
@@ -21,6 +21,8 @@
  * questions.
  */
 
+package test;
+
 public interface J {
     public default Foo m() { return null; }
 }
--- a/test/hotspot/jtreg/runtime/LoaderConstraints/common/PreemptingClassLoader.java	Mon May 07 14:42:10 2018 +0200
+++ b/test/hotspot/jtreg/runtime/LoaderConstraints/common/PreemptingClassLoader.java	Mon May 07 11:38:21 2018 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2018, 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
@@ -27,14 +27,26 @@
 public class PreemptingClassLoader extends ClassLoader {
 
     private final Set<String> names = new HashSet<>();
+    boolean checkLoaded = true;
 
     public PreemptingClassLoader(String... names) {
         for (String n : names) this.names.add(n);
     }
 
+    public PreemptingClassLoader(String name, String[] names) {
+        super(name, ClassLoader.getSystemClassLoader());
+        for (String n : names) this.names.add(n);
+    }
+
+    public PreemptingClassLoader(String name, String[] names, boolean cL) {
+        super(name, ClassLoader.getSystemClassLoader());
+        for (String n : names) this.names.add(n);
+        checkLoaded = cL;
+    }
+
     protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
         if (!names.contains(name)) return super.loadClass(name, resolve);
-        Class<?> result = findLoadedClass(name);
+        Class<?> result = checkLoaded ? findLoadedClass(name) : null;
         if (result == null) {
             String filename = name.replace('.', '/') + ".class";
             try (InputStream data = getResourceAsStream(filename)) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/LoaderConstraints/differentLE/D_ambgs.jasm	Mon May 07 11:38:21 2018 +0200
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2018, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+package test;
+
+// A simple class to extend an abstract class and get loaded with different
+// loaders.  This class is loaded via Loader2.  A similar named class will
+// be loaded via the bootstrap loader.
+//
+// The following code is implemented as java assembler to avoid checks
+// of javac.
+//
+// public class D_ambgs extends bug_21227 {
+//  
+//     D_ambgs() {
+//         System.out.println("Gonna hack this thing");
+//     }
+//
+//     public D_ambgs[] make(A iface) { 
+//         throw new Error("do not call me");
+//     }
+// }
+
+class D_ambgs extends C {
+
+    Method D_ambgs:"()V"
+        stack 2 locals 1
+    {
+        aload_0;
+        invokespecial Method test/C."<init>":"()V";
+        getstatic     Field java/lang/System.out:"Ljava/io/PrintStream;";
+        ldc           String "Gonna hack this thing";
+        invokevirtual Method java/io/PrintStream.println:"(Ljava/lang/String;)V";
+        return;
+    }
+
+    public Method make:"(Ltest/A;)[Ltest/D_ambgs;"
+        stack 3 locals 2
+    {
+         new           class java/lang/Error;
+         dup;
+         ldc           String "do not call me";
+         invokespecial Method java/lang/Error."<init>":"(Ljava/lang/String;)V";
+         athrow;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/LoaderConstraints/differentLE/Test.java	Mon May 07 11:38:21 2018 +0200
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018 SAP SE. 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @bug 8199852
+ * @summary Test exception messages of LinkageError. Two class loaders load
+ *          two different versions of a class. Should trigger exception in
+ *          SystemDictionary::check_constraints().
+ * @library /test/lib
+ * @compile D_ambgs.jasm
+ * @run driver ClassFileInstaller test.D_ambgs
+ * @compile  ../common/PreemptingClassLoader.java
+ *           test/D_ambgs.java Test.java test/B.java
+ * @run driver ClassFileInstaller test.B
+ * @run main/othervm Test
+ */
+
+import test.*;
+
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+
+import java.io.*;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+public class Test {
+
+    //  Force LinkageError.
+    //
+    //  Derived from test runtime/6626217.
+    //
+    //  Uses the specialized class loader PreemptingClassLoader.
+    //  PreemptingClassLoader only loads files with names passed to it in its
+    //  constructor. If it does not find it, it delegates to the super class loader.
+    //
+    //  A    // interface
+    //  |
+    //  B    // Compiled to the current working directory so that it is found by our
+    //       // special class loader. B uses D, so that loading B triggers loading D.
+    //
+    //  C    // An abstract class.
+    //  |
+    //  D    // Class with two different implementations D1 and D2. D2 is
+    //       // compiled to the current working directory so that it is found by our
+    //       // special class loader.
+    //
+    // First, the bootstrap loader will load D1. It already has loaded interface A.
+    // Then, the second class loader PreemptingClassLoader will load B. Recursive,
+    // it tries to load interface A. As it does not find it (there is no A.impl2),
+    // it asks the super classloader for A.
+    // Then it loads the D2 variant of D from the current working directory and it's
+    // superclass C. This fails as D1 is already loaded with the same superclass.
+
+    static String expectedErrorMessage =
+        "loader constraint violation: loader \"<unnamed>\" (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).";
+
+    public static void test_access() throws Exception {
+        try {
+            // Make a Class 'D_ambgs' under the default loader.
+            // This uses the implementation from the .java file.
+            C c_1 = new D_ambgs();
+
+            // Some classes under a new Loader, loader2, including, indirectly,
+            // another version of 'D_ambgs'
+            String[] classNames = {"test.B", "test.D_ambgs"};
+
+            ClassLoader loader2 = new PreemptingClassLoader(null, classNames, false);
+            Class       class2  = loader2.loadClass("test.B");
+            A           iface   = (A)class2.newInstance();
+
+            // Call D1.make() loaded by bootstrap loader with B loaded by Loader2.
+            D_ambgs[] x2 = c_1.make(iface);
+
+            throw new RuntimeException("Expected LinkageError was not thrown.");
+        } catch (LinkageError jle) {
+            String errorMsg = jle.getMessage();
+            if (!errorMsg.equals(expectedErrorMessage)) {
+                System.out.println("Expected: " + expectedErrorMessage + "\n" +
+                                   "but got:  " + errorMsg);
+                throw new RuntimeException("Wrong error message of LinkageError.");
+            } else {
+                System.out.println("Passed with message: " + errorMsg);
+            }
+        }
+    }
+
+    public static void main(String[] args) throws Exception {
+        test_access();
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/LoaderConstraints/differentLE/test/A.java	Mon May 07 11:38:21 2018 +0200
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2018, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+package test;
+
+// A simple interface, to allow an unknown foreign call from a class
+// loaded with the bootstrap loader to a class loaded with Loader2.
+public interface A {
+    public D_ambgs[] gen();
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/LoaderConstraints/differentLE/test/B.java	Mon May 07 11:38:21 2018 +0200
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2018, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+package test;
+
+// This class is loaded via Loader2. Using D_ambgs here will trigger
+// loading it's second version with Loader2.
+public class B implements A {
+    public D_ambgs[] gen() {
+        D_ambgs[] x = new D_ambgs[1];
+        x[0] = new D_ambgs();
+        return x;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/LoaderConstraints/differentLE/test/C.java	Mon May 07 11:38:21 2018 +0200
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2018, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+package test;
+
+abstract public class C {
+    public abstract D_ambgs[] make(A iface); // abstract factory
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/LoaderConstraints/differentLE/test/D_ambgs.java	Mon May 07 11:38:21 2018 +0200
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2018, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+package test;
+
+// A simple class to extend an abstract class and get loaded with different
+// loaders. This class is loaded via the bootstrap loader. A similar named class will
+// be loaded via Loader2.
+public class D_ambgs extends C {
+
+    // We are loaded by the bootstrap loader. iface is an object of a class
+    // loaded by Loader2. As it references D_ambgs, Loader2 will trigger
+    // loading the version known to it, which differs from this one.
+    public D_ambgs[] make(A iface) {
+        // This function needs to return a value known to be loaded from Loader2.
+        // Since I need to use a yet different loader, I need to make an unknown
+        // foreign call. In this case I'll be using an interface to make the
+        // unknown call, with but a single implementor so the compiler can do the
+        // upcast statically.
+        return iface == null ? null : iface.gen();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/LoaderConstraints/duplicateLE/Test.java	Mon May 07 11:38:21 2018 +0200
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2018, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @bug 8199852
+ * @summary Test exception messages of LinkageError. A class loader loads
+ *          twice the same class. Should trigger exception in
+ *          SystemDictionary::check_constraints().
+ * @compile ../common/Foo.java
+ * @compile ../common/J.java
+ *          ../common/PreemptingClassLoader.java
+ * @run main/othervm Test
+ */
+
+public class Test {
+
+    // Check that all names have external formatting ('.' and not '/' in package names).
+    // Check for parent of class loader.
+    static String expectedErrorMessage1 =
+        "loader \"<unnamed>\" (instance of PreemptingClassLoader, " +
+        "child of \"app\" jdk.internal.loader.ClassLoaders$AppClassLoader) " +
+        "attempted duplicate class definition for test.Foo.";
+
+    // Check that all names have external formatting ('.' and not '/' in package names).
+    // Check for name and parent of class loader.
+    static String expectedErrorMessage2 =
+        "loader \"DuplicateLE_Test_Loader\" (instance of PreemptingClassLoader, " +
+        "child of \"app\" jdk.internal.loader.ClassLoaders$AppClassLoader) " +
+        "attempted duplicate class definition for test.Foo.";
+
+    // 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 =
+        "loader \"DuplicateLE_Test_Loader_IF\" (instance of PreemptingClassLoader, " +
+        "child of \"app\" jdk.internal.loader.ClassLoaders$AppClassLoader) " +
+        "attempted duplicate interface definition for test.J.";
+
+    // Test that the error message is correct when a loader constraint error is
+    // detected during vtable creation.
+    //
+    // In this test, during vtable creation for class Task, method "Task.m()LFoo;"
+    // 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, String testType) throws Exception {
+        String[] classNames = {testType};
+        ClassLoader l = new PreemptingClassLoader(loaderName, classNames, false);
+        l.loadClass(testType);
+        try {
+            l.loadClass(testType).newInstance();
+            throw new RuntimeException("Expected LinkageError exception not thrown");
+        } catch (LinkageError e) {
+            String errorMsg = e.getMessage();
+            if (!errorMsg.equals(expectedErrorMessage)) {
+                System.out.println("Expected: " + expectedErrorMessage + "\n" +
+                                   "but got:  " + errorMsg);
+                throw new RuntimeException("Wrong LinkageError exception thrown: " + errorMsg);
+            }
+            System.out.println("Passed with message: " + errorMsg);
+        }
+    }
+
+    public static void main(String args[]) throws Exception {
+        test(null, expectedErrorMessage1, "test.Foo");
+        test("DuplicateLE_Test_Loader", expectedErrorMessage2, "test.Foo");
+        test("DuplicateLE_Test_Loader_IF", expectedErrorMessage3, "test.J");
+    }
+}
+
--- a/test/hotspot/jtreg/runtime/LoaderConstraints/itableICCE/I.java	Mon May 07 14:42:10 2018 +0200
+++ b/test/hotspot/jtreg/runtime/LoaderConstraints/itableICCE/I.java	Mon May 07 11:38:21 2018 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2018, 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
@@ -21,6 +21,8 @@
  * questions.
  */
 
+package test;
+
 public interface I {
     public default Foo m() { return null; }
 }
--- a/test/hotspot/jtreg/runtime/LoaderConstraints/itableICCE/Task.java	Mon May 07 14:42:10 2018 +0200
+++ b/test/hotspot/jtreg/runtime/LoaderConstraints/itableICCE/Task.java	Mon May 07 11:38:21 2018 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2018, 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
@@ -21,6 +21,8 @@
  * questions.
  */
 
+package test;
+
 public class Task implements Runnable {
 
     public void run() {
--- a/test/hotspot/jtreg/runtime/LoaderConstraints/itableICCE/Test.java	Mon May 07 14:42:10 2018 +0200
+++ b/test/hotspot/jtreg/runtime/LoaderConstraints/itableICCE/Test.java	Mon May 07 11:38:21 2018 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2018, 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
@@ -44,14 +44,14 @@
     // ICCE). So, no LinkageError exception should be thrown because the loader
     // constraint check that would cause the LinkageError should not be done.
     public static void main(String... args) throws Exception {
-        Class<?> c = Foo.class; // forces standard class loader to load Foo
-        ClassLoader l = new PreemptingClassLoader("Task", "Foo", "C", "I");
-        Runnable r = (Runnable) l.loadClass("Task").newInstance();
+        Class<?> c = test.Foo.class; // forces standard class loader to load Foo
+        ClassLoader l = new PreemptingClassLoader("test.Task", "test.Foo", "test.C", "test.I");
+        Runnable r = (Runnable) l.loadClass("test.Task").newInstance();
         try {
             r.run(); // Cause an ICCE because both I and J define m()LFoo;
             throw new RuntimeException("Expected ICCE exception not thrown");
         } catch (IncompatibleClassChangeError e) {
-            if (!e.getMessage().contains("Conflicting default methods: I.m J.m")) {
+            if (!e.getMessage().contains("Conflicting default methods: test/I.m test/J.m")) {
                 throw new RuntimeException("Wrong ICCE exception thrown: " + e.getMessage());
             }
         }
--- a/test/hotspot/jtreg/runtime/LoaderConstraints/itableLdrConstraint/I.java	Mon May 07 14:42:10 2018 +0200
+++ b/test/hotspot/jtreg/runtime/LoaderConstraints/itableLdrConstraint/I.java	Mon May 07 11:38:21 2018 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2018, 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
@@ -21,6 +21,8 @@
  * questions.
  */
 
+package test;
+
 public interface I {
     public Foo m();
 }
--- a/test/hotspot/jtreg/runtime/LoaderConstraints/itableLdrConstraint/Task.java	Mon May 07 14:42:10 2018 +0200
+++ b/test/hotspot/jtreg/runtime/LoaderConstraints/itableLdrConstraint/Task.java	Mon May 07 11:38:21 2018 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2018, 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
@@ -21,6 +21,8 @@
  * questions.
  */
 
+package test;
+
 public class Task implements Runnable {
 
     public void run() {
--- a/test/hotspot/jtreg/runtime/LoaderConstraints/itableLdrConstraint/Test.java	Mon May 07 14:42:10 2018 +0200
+++ b/test/hotspot/jtreg/runtime/LoaderConstraints/itableLdrConstraint/Test.java	Mon May 07 11:38:21 2018 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2018, 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
@@ -23,7 +23,7 @@
 
 /*
  * @test
- * @bug 8186092
+ * @bug 8186092 8199852
  * @compile ../common/Foo.java
  *          ../common/J.java
  *          I.java
@@ -35,6 +35,26 @@
 
 public class Test {
 
+    static String expectedErrorMessage1 =
+        "loader constraint violation in interface itable initialization for class test.C: " +
+        "when selecting method test.I.m()Ltest/Foo; " +
+        "the class loader \"<unnamed>\" (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 =
+        "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\" (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";
+
     // Test that the error message is correct when a loader constraint error is
     // detected during itable creation.
     //
@@ -43,18 +63,27 @@
     // type super interface J.  The selected method is not an overpass method nor
     // otherwise excluded from loader constraint checking.  So, a LinkageError
     // exception should be thrown because the loader constraint check will fail.
-    public static void main(String... args) throws Exception {
-        Class<?> c = Foo.class; // forces standard class loader to load Foo
-        ClassLoader l = new PreemptingClassLoader("Task", "Foo", "C", "I");
-        Runnable r = (Runnable) l.loadClass("Task").newInstance();
+    public static void test(String loaderName, String expectedErrorMessage) 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);
+        Runnable r = (Runnable) l.loadClass("test.Task").newInstance();
         try {
             r.run();
             throw new RuntimeException("Expected LinkageError exception not thrown");
         } catch (LinkageError e) {
-            if (!e.getMessage().contains(
-                "loader constraint violation in interface itable initialization for class C:")) {
-                throw new RuntimeException("Wrong LinkageError exception thrown: " + e.getMessage());
+            String errorMsg = e.getMessage();
+            if (!errorMsg.equals(expectedErrorMessage)) {
+                System.out.println("Expected: " + expectedErrorMessage + "\n" +
+                                   "but got:  " + errorMsg);
+                throw new RuntimeException("Wrong LinkageError exception thrown: " + errorMsg);
             }
+            System.out.println("Passed with message: " + errorMsg);
         }
     }
+
+    public static void main(String... args) throws Exception {
+        test(null, expectedErrorMessage1);
+        test("ItableLdrCnstrnt_Test_Loader", expectedErrorMessage2);
+    }
 }
--- a/test/hotspot/jtreg/runtime/LoaderConstraints/vtableAME/I.java	Mon May 07 14:42:10 2018 +0200
+++ b/test/hotspot/jtreg/runtime/LoaderConstraints/vtableAME/I.java	Mon May 07 11:38:21 2018 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2018, 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
@@ -21,6 +21,8 @@
  * questions.
  */
 
+package test;
+
 public interface I extends J {
     public Foo m();
 }
--- a/test/hotspot/jtreg/runtime/LoaderConstraints/vtableAME/Task.java	Mon May 07 14:42:10 2018 +0200
+++ b/test/hotspot/jtreg/runtime/LoaderConstraints/vtableAME/Task.java	Mon May 07 11:38:21 2018 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2018, 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
@@ -21,4 +21,6 @@
  * questions.
  */
 
+package test;
+
 public class Task extends C { }
--- a/test/hotspot/jtreg/runtime/LoaderConstraints/vtableAME/Test.java	Mon May 07 14:42:10 2018 +0200
+++ b/test/hotspot/jtreg/runtime/LoaderConstraints/vtableAME/Test.java	Mon May 07 11:38:21 2018 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2018, 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
@@ -48,16 +48,16 @@
     // because the loader constraint check that would cause the LinkageError
     // should not be done.
     public static void main(String args[]) throws Exception {
-        Class<?> c = Foo.class; // forces standard class loader to load Foo
-        ClassLoader l = new PreemptingClassLoader("Task", "Foo", "I", "J");
-        l.loadClass("Foo");
-        l.loadClass("Task").newInstance();
-        Task t = new Task();
+        Class<?> c = test.Foo.class; // forces standard class loader to load Foo
+        ClassLoader l = new PreemptingClassLoader("test.Task", "test.Foo", "test.I", "test.J");
+        l.loadClass("test.Foo");
+        l.loadClass("test.Task").newInstance();
+        test.Task t = new test.Task();
         try {
             t.m(); // Should get AME
             throw new RuntimeException("Missing AbstractMethodError exception");
         } catch (AbstractMethodError e) {
-            if (!e.getMessage().contains("Method Task.m()LFoo; is abstract")) {
+            if (!e.getMessage().contains("Method test/Task.m()Ltest/Foo; is abstract")) {
                 throw new RuntimeException("Wrong AME exception thrown: " + e.getMessage());
             }
         }
--- a/test/hotspot/jtreg/runtime/LoaderConstraints/vtableLdrConstraint/I.java	Mon May 07 14:42:10 2018 +0200
+++ b/test/hotspot/jtreg/runtime/LoaderConstraints/vtableLdrConstraint/I.java	Mon May 07 11:38:21 2018 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2018, 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
@@ -21,5 +21,7 @@
  * questions.
  */
 
+package test;
+
 public interface I extends J {
 }
--- a/test/hotspot/jtreg/runtime/LoaderConstraints/vtableLdrConstraint/Task.java	Mon May 07 14:42:10 2018 +0200
+++ b/test/hotspot/jtreg/runtime/LoaderConstraints/vtableLdrConstraint/Task.java	Mon May 07 11:38:21 2018 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2018, 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
@@ -21,6 +21,8 @@
  * questions.
  */
 
+package test;
+
 public class Task extends C {
 
     public Foo m() {
--- a/test/hotspot/jtreg/runtime/LoaderConstraints/vtableLdrConstraint/Test.java	Mon May 07 14:42:10 2018 +0200
+++ b/test/hotspot/jtreg/runtime/LoaderConstraints/vtableLdrConstraint/Test.java	Mon May 07 11:38:21 2018 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2018, 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
@@ -23,7 +23,7 @@
 
 /*
  * @test
- * @bug 8186092
+ * @bug 8186092 8199852
  * @compile ../common/Foo.java
  *          ../common/J.java
  *          I.java
@@ -35,6 +35,26 @@
 
 public class Test {
 
+    static String expectedErrorMessage1 =
+        "loader constraint violation for class test.Task: " +
+        "when selecting overriding method test.Task.m()Ltest/Foo; " +
+        "the class loader \"<unnamed>\" (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 =
+        "loader constraint violation for class test.Task: " +
+        "when selecting overriding method test.Task.m()Ltest/Foo; " +
+        "the class loader \"VtableLdrCnstrnt_Test_Loader\" (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";
+
     // Test that the error message is correct when a loader constraint error is
     // detected during vtable creation.
     //
@@ -42,22 +62,28 @@
     // 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 main(String args[]) throws Exception {
-        Class<?> c = Foo.class; // forces standard class loader to load Foo
-        ClassLoader l = new PreemptingClassLoader("Task", "Foo", "I");
-        l.loadClass("Foo");
+    public static void test(String loaderName, String expectedErrorMessage) 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);
+        l.loadClass("test.Foo");
         try {
-            l.loadClass("Task").newInstance();
+            l.loadClass("test.Task").newInstance();
             throw new RuntimeException("Expected LinkageError exception not thrown");
         } catch (LinkageError e) {
-            if (!e.getMessage().contains(
-                    "loader constraint violation for class Task: when selecting overriding method") ||
-                !e.getMessage().contains(
-                    "for its super type J have different Class objects for the type Foo")) {
-                throw new RuntimeException("Wrong LinkageError exception thrown: " + e.getMessage());
+            String errorMsg = e.getMessage();
+            if (!errorMsg.equals(expectedErrorMessage)) {
+                System.out.println("Expected: " + expectedErrorMessage + "\n" +
+                                   "but got:  " + errorMsg);
+                throw new RuntimeException("Wrong LinkageError exception thrown: " + errorMsg);
             }
+            System.out.println("Passed with message: " + errorMsg);
         }
     }
 
+    public static void main(String args[]) throws Exception {
+        test(null, expectedErrorMessage1);
+        test("VtableLdrCnstrnt_Test_Loader", expectedErrorMessage2);
+    }
 }