8186092
: Unnecessary loader constraints produced when there are multiple defaults
Do not check loader constraints for overpass methods Reviewed-by: dholmes, acorn
This commit is contained in:
parent
394e6a8318
commit
87e30fd801
@ -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 @@ static void create_default_methods( InstanceKlass* klass,
|
||||
// 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<Method*>* mirandas, TRAPS) {
|
||||
@ -901,6 +900,11 @@ static void switchover_constant_pool(BytecodeConstantPool* bpool,
|
||||
// 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<EmptyVtableSlot*>* slots,
|
||||
InstanceKlass* klass, TRAPS) {
|
||||
|
@ -479,13 +479,15 @@ bool klassVtable::update_inherited_vtable(InstanceKlass* klass, const methodHand
|
||||
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.
|
||||
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 +497,23 @@ bool klassVtable::update_inherited_vtable(InstanceKlass* klass, const methodHand
|
||||
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 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 "
|
||||
"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 +1197,15 @@ void klassItable::initialize_itable_for_interface(int method_table_offset, Klass
|
||||
// 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 +1219,24 @@ void klassItable::initialize_itable_for_interface(int method_table_offset, Klass
|
||||
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 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"
|
||||
" 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);
|
||||
}
|
||||
}
|
||||
|
37
test/hotspot/jtreg/runtime/LoaderConstraints/common/C.jasm
Normal file
37
test/hotspot/jtreg/runtime/LoaderConstraints/common/C.jasm
Normal file
@ -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 "<init>":"()V" stack 1 locals 1 {
|
||||
aload_0;
|
||||
invokespecial Method java/lang/Object."<init>":"()V";
|
||||
return;
|
||||
}
|
||||
|
||||
} // end Class C
|
24
test/hotspot/jtreg/runtime/LoaderConstraints/common/Foo.java
Normal file
24
test/hotspot/jtreg/runtime/LoaderConstraints/common/Foo.java
Normal file
@ -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 {}
|
26
test/hotspot/jtreg/runtime/LoaderConstraints/common/J.java
Normal file
26
test/hotspot/jtreg/runtime/LoaderConstraints/common/J.java
Normal file
@ -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; }
|
||||
}
|
@ -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<String> 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;
|
||||
}
|
||||
|
||||
}
|
@ -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; }
|
||||
}
|
@ -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();
|
||||
}
|
||||
}
|
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
@ -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();
|
||||
}
|
||||
}
|
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
@ -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 { }
|
@ -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 inheriting 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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -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 {
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
@ -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 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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user