--- old/src/hotspot/share/classfile/defaultMethods.cpp 2017-09-27 09:30:41.350986164 -0400 +++ new/src/hotspot/share/classfile/defaultMethods.cpp 2017-09-27 09:30:41.052132327 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2017, 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 @@ -767,15 +767,14 @@ // This is the guts of the default methods implementation. This is called just // after the classfile has been parsed if some ancestor has default methods. // -// First if finds any name/signature slots that need any implementation (either +// First it finds any name/signature slots that need any implementation (either // because they are miranda or a superclass's implementation is an overpass // itself). For each slot, iterate over the hierarchy, to see if they contain a // signature that matches the slot we are looking at. // -// For each slot filled, we generate an overpass method that either calls the -// unique default method candidate using invokespecial, or throws an exception -// (in the case of no default method candidates, or more than one valid -// candidate). These methods are then added to the class's method list. +// For each slot filled, we either record the default method candidate in the +// klass default_methods list or, only to handle exception cases, we create an +// overpass method that throws an exception and add it to the klass methods list. // The JVM does not create bridges nor handle generic signatures here. void DefaultMethods::generate_default_methods( InstanceKlass* klass, const GrowableArray* mirandas, TRAPS) { @@ -901,6 +900,11 @@ // This allows virtual methods to override the overpass, but ensures // that a local method search will find the exception rather than an abstract // or default method that is not a valid candidate. +// +// Note that if overpass method are ever created that are not exception +// throwing methods then the loader constraint checking logic for vtable and +// itable creation needs to be changed to check loader constraints for the +// overpass methods that do not throw exceptions. static void create_defaults_and_exceptions( GrowableArray* slots, InstanceKlass* klass, TRAPS) { --- old/src/hotspot/share/oops/klassVtable.cpp 2017-09-27 09:30:42.050117724 -0400 +++ new/src/hotspot/share/oops/klassVtable.cpp 2017-09-27 09:30:41.739469669 -0400 @@ -479,13 +479,16 @@ allocate_new = false; } - if (checkconstraints) { - // Override vtable entry if passes loader constraint check - // if loader constraint checking requested - // No need to visit his super, since he and his super - // have already made any needed loader constraints. - // Since loader constraints are transitive, it is enough - // to link to the first super, and we get all the others. + // Do not check loader constraints for overpass methods because overpass + // methods are created by the jvm to throw exceptions. They are not + // resolved methods. + if (checkconstraints && !target_method()->is_overpass()) { + // Override vtable entry if passes loader constraint check + // if loader constraint checking requested + // No need to visit his super, since he and his super + // have already made any needed loader constraints. + // Since loader constraints are transitive, it is enough + // to link to the first super, and we get all the others. Handle super_loader(THREAD, super_klass->class_loader()); if (target_loader() != super_loader()) { @@ -495,21 +498,23 @@ super_loader, true, CHECK_(false)); if (failed_type_symbol != NULL) { - const char* msg = "loader constraint violation: when resolving " - "overridden method \"%s\" the class loader (instance" - " of %s) of the current class, %s, and its superclass loader " - "(instance of %s), have different Class objects for the type " - "%s used in the signature"; + const char* msg = "loader constraint violation for class %s: when resolving " + "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 " + "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* current = target_klass->name()->as_C_string(); + 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(sig) + strlen(loader1) + - strlen(current) + strlen(loader2) + strlen(failed_type_name); + size_t buflen = strlen(msg) + strlen(curr_class) + strlen(sig) + + 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, sig, loader1, current, loader2, - failed_type_name); + jio_snprintf(buf, buflen, msg, curr_class, sig, loader1, sel_class, loader2, + super_class, failed_type_name); THROW_MSG_(vmSymbols::java_lang_LinkageError(), buf, false); } } @@ -1193,13 +1198,15 @@ // to correctly enforce loader constraints for interface method inheritance target = LinkResolver::lookup_instance_method_in_klasses(_klass, m->name(), m->signature(), CHECK); } - if (target == NULL || !target->is_public() || target->is_abstract()) { - // Entry does not resolve. Leave it empty for AbstractMethodError. - if (!(target == NULL) && !target->is_public()) { - // Stuff an IllegalAccessError throwing method in there instead. - itableOffsetEntry::method_entry(_klass, method_table_offset)[m->itable_index()]. - initialize(Universe::throw_illegal_access_error()); - } + if (target == NULL || !target->is_public() || target->is_abstract() || target->is_overpass()) { + assert(target == NULL || !target->is_overpass() || target->is_public(), + "Non-public overpass method!"); + // Entry does not resolve. Leave it empty for AbstractMethodError or other error. + if (!(target == NULL) && !target->is_public()) { + // Stuff an IllegalAccessError throwing method in there instead. + itableOffsetEntry::method_entry(_klass, method_table_offset)[m->itable_index()]. + initialize(Universe::throw_illegal_access_error()); + } } else { // Entry did resolve, check loader constraints before initializing // if checkconstraints requested @@ -1213,24 +1220,24 @@ interface_loader, true, CHECK); if (failed_type_symbol != NULL) { - const char* msg = "loader constraint violation in interface " - "itable initialization: when resolving method \"%s\" the class" - " loader (instance of %s) of the current class, %s, " - "and the class loader (instance of %s) for interface " - "%s have different Class objects for the type %s " - "used in the signature"; - char* sig = target()->name_and_sig_as_C_string(); - const char* loader1 = SystemDictionary::loader_name(method_holder_loader()); + const char* msg = "loader constraint violation in interface itable" + " initialization for class %s: when resolving 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" + " different Class objects for the type %s used in the signature"; char* current = _klass->name()->as_C_string(); - const char* loader2 = SystemDictionary::loader_name(interface_loader()); + 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(); - size_t buflen = strlen(msg) + strlen(sig) + strlen(loader1) + - strlen(current) + strlen(loader2) + strlen(iface) + + 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, sig, loader1, current, loader2, - iface, failed_type_name); + jio_snprintf(buf, buflen, msg, current, sig, loader1, iface, + loader2, mclass, failed_type_name); THROW_MSG(vmSymbols::java_lang_LinkageError(), buf); } } --- /dev/null 2017-08-03 13:42:08.516000218 -0400 +++ new/test/hotspot/jtreg/runtime/LoaderConstraints/common/C.jasm 2017-09-27 09:30:42.453842925 -0400 @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2017, 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. + */ + +// If this file was written in java then some of the tests would fail during +// compilation with errors such as: +// 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 + +super public class C implements I, J version 52:0 { + + public Method "":"()V" stack 1 locals 1 { + aload_0; + invokespecial Method java/lang/Object."":"()V"; + return; + } + +} // end Class C --- /dev/null 2017-08-03 13:42:08.516000218 -0400 +++ new/test/hotspot/jtreg/runtime/LoaderConstraints/common/Foo.java 2017-09-27 09:30:43.091086537 -0400 @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2017, 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. + */ + +public class Foo {} --- /dev/null 2017-08-03 13:42:08.516000218 -0400 +++ new/test/hotspot/jtreg/runtime/LoaderConstraints/common/J.java 2017-09-27 09:30:43.738098319 -0400 @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2017, 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. + */ + +public interface J { + public default Foo m() { return null; } +} --- /dev/null 2017-08-03 13:42:08.516000218 -0400 +++ new/test/hotspot/jtreg/runtime/LoaderConstraints/common/PreemptingClassLoader.java 2017-09-27 09:30:44.386078053 -0400 @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2017, 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. + */ + +import java.util.*; +import java.io.*; + +public class PreemptingClassLoader extends ClassLoader { + + private final Set names = new HashSet<>(); + + public PreemptingClassLoader(String... names) { + for (String n : names) this.names.add(n); + } + + protected Class loadClass(String name, boolean resolve) throws ClassNotFoundException { + if (!names.contains(name)) return super.loadClass(name, resolve); + Class result = findLoadedClass(name); + if (result == null) { + String filename = name.replace('.', '/') + ".class"; + try (InputStream data = getResourceAsStream(filename)) { + if (data == null) throw new ClassNotFoundException(); + try (ByteArrayOutputStream buffer = new ByteArrayOutputStream()) { + int b; + do { + b = data.read(); + if (b >= 0) buffer.write(b); + } while (b >= 0); + byte[] bytes = buffer.toByteArray(); + result = defineClass(name, bytes, 0, bytes.length); + } + } catch (IOException e) { + throw new ClassNotFoundException("Error reading class file", e); + } + } + if (resolve) resolveClass(result); + return result; + } + +} --- /dev/null 2017-08-03 13:42:08.516000218 -0400 +++ new/test/hotspot/jtreg/runtime/LoaderConstraints/itableICCE/I.java 2017-09-27 09:30:45.024680576 -0400 @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2017, 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. + */ + +public interface I { + public default Foo m() { return null; } +} --- /dev/null 2017-08-03 13:42:08.516000218 -0400 +++ new/test/hotspot/jtreg/runtime/LoaderConstraints/itableICCE/Task.java 2017-09-27 09:30:45.657521554 -0400 @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2017, 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. + */ + +public class Task implements Runnable { + + public void run() { + Class c = Foo.class; // forces PreemptingClassLoader to load Foo + C x = new C(); // should not trigger loader constraints exception + x.m(); + } +} --- /dev/null 2017-08-03 13:42:08.516000218 -0400 +++ new/test/hotspot/jtreg/runtime/LoaderConstraints/itableICCE/Test.java 2017-09-27 09:30:46.319504776 -0400 @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2017, 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 8186092 + * @compile ../common/Foo.java + * I.java + * ../common/J.java + * ../common/C.jasm + * Task.java + * ../common/PreemptingClassLoader.java + * @run main/othervm Test + */ + +public class Test { + + // Test that LinkageError exceptions are not thrown during itable creation, + // for loader constraint errors, if the target method is an overpass method. + // + // In this test, during itable creation for class C, method "m()LFoo;" for + // C's super interface I has a different class Foo than the selected method's + // type J. But, the selected method is an overpass method (that throws an + // 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(); + 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")) { + throw new RuntimeException("Wrong ICCE exception thrown: " + e.getMessage()); + } + } + } +} --- /dev/null 2017-08-03 13:42:08.516000218 -0400 +++ new/test/hotspot/jtreg/runtime/LoaderConstraints/itableLdrConstraint/I.java 2017-09-27 09:30:46.955298142 -0400 @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2017, 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. + */ + +public interface I { + public Foo m(); +} --- /dev/null 2017-08-03 13:42:08.516000218 -0400 +++ new/test/hotspot/jtreg/runtime/LoaderConstraints/itableLdrConstraint/Task.java 2017-09-27 09:30:47.595310971 -0400 @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2017, 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. + */ + +public class Task implements Runnable { + + public void run() { + Class c = Foo.class; // forces PreemptingClassLoader to load Foo + C x = new C(); // triggers overloading constraints + x.m(); + } +} --- /dev/null 2017-08-03 13:42:08.516000218 -0400 +++ new/test/hotspot/jtreg/runtime/LoaderConstraints/itableLdrConstraint/Test.java 2017-09-27 09:30:48.244152634 -0400 @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2017, 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 8186092 + * @compile ../common/Foo.java + * ../common/J.java + * I.java + * ../common/C.jasm + * Task.java + * ../common/PreemptingClassLoader.java + * @run main/othervm Test + */ + +public class Test { + + // Test that the error message is correct when a loader constraint error is + // detected during itable creation. + // + // In this test, during itable creation for class C, method "m()LFoo;" for + // C's super interface I has a different class Foo than the selected method's + // 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(); + 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()); + } + } + } +} --- /dev/null 2017-08-03 13:42:08.516000218 -0400 +++ new/test/hotspot/jtreg/runtime/LoaderConstraints/vtableAME/I.java 2017-09-27 09:30:48.885078665 -0400 @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2017, 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. + */ + +public interface I extends J { + public Foo m(); +} --- /dev/null 2017-08-03 13:42:08.516000218 -0400 +++ new/test/hotspot/jtreg/runtime/LoaderConstraints/vtableAME/Task.java 2017-09-27 09:30:49.532889859 -0400 @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2017, 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. + */ + +public class Task extends C { } --- /dev/null 2017-08-03 13:42:08.516000218 -0400 +++ new/test/hotspot/jtreg/runtime/LoaderConstraints/vtableAME/Test.java 2017-09-27 09:30:50.182247345 -0400 @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2017, 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 8186092 + * @compile ../common/Foo.java + * ../common/J.java + * I.java + * ../common/C.jasm + * Task.java + * ../common/PreemptingClassLoader.java + * @run main/othervm Test + */ + +import java.io.PrintStream; +import java.lang.reflect.*; + +public class Test { + + // Test that LinkageError exceptions are not thrown during vtable creation, + // for loader constraint errors, if the target method is an overpass method. + // + // In this test, during vtable creation for class Task, the target method + // "Task.m()LFoo;" is an overpass method (that throws an AME). So, even + // though it is inheritting the method from its super class C, and Task has + // a different class Foo than C, 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", "I", "J"); + l.loadClass("Foo"); + l.loadClass("Task").newInstance(); + Task t = new 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")) { + throw new RuntimeException("Wrong AME exception thrown: " + e.getMessage()); + } + } + } + +} --- /dev/null 2017-08-03 13:42:08.516000218 -0400 +++ new/test/hotspot/jtreg/runtime/LoaderConstraints/vtableLdrConstraint/I.java 2017-09-27 09:30:50.832161753 -0400 @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2017, 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. + */ + +public interface I extends J { +} --- /dev/null 2017-08-03 13:42:08.516000218 -0400 +++ new/test/hotspot/jtreg/runtime/LoaderConstraints/vtableLdrConstraint/Task.java 2017-09-27 09:30:51.482791264 -0400 @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2017, 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. + */ + +public class Task extends C { + + public Foo m() { + return null; + } + +} --- /dev/null 2017-08-03 13:42:08.516000218 -0400 +++ new/test/hotspot/jtreg/runtime/LoaderConstraints/vtableLdrConstraint/Test.java 2017-09-27 09:30:52.130021499 -0400 @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2017, 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 8186092 + * @compile ../common/Foo.java + * ../common/J.java + * I.java + * ../common/C.jasm + * Task.java + * ../common/PreemptingClassLoader.java + * @run main/othervm Test + */ + +public class Test { + + // 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 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"); + try { + l.loadClass("Task").newInstance(); + throw new RuntimeException("Expected LinkageError exception not thrown"); + } catch (LinkageError e) { + if (!e.getMessage().contains( + "loader constraint violation for class Task: when resolving 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()); + } + } + } + +} +