Path: blob/master/test/hotspot/jtreg/vmTestbase/vm/runtime/defmeth/BasicTest.java
41159 views
/*1* Copyright (c) 2013, 2021, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223/*24* @test25*26* @modules java.base/jdk.internal.org.objectweb.asm:+open java.base/jdk.internal.org.objectweb.asm.util:+open27* @library /vmTestbase /test/lib28*29* @comment build retransform.jar in current dir30* @run driver vm.runtime.defmeth.shared.BuildJar31*32* @run driver jdk.test.lib.FileInstaller . .33* @run main/othervm/native34* -agentlib:redefineClasses35* -javaagent:retransform.jar36* vm.runtime.defmeth.BasicTest37*/3839package vm.runtime.defmeth;4041import java.util.Map;42import java.util.Set;4344import nsk.share.TestFailure;45import vm.runtime.defmeth.shared.MemoryClassLoader;46import vm.runtime.defmeth.shared.annotation.NotApplicableFor;47import vm.runtime.defmeth.shared.builder.TestBuilder;48import vm.runtime.defmeth.shared.data.*;49import vm.runtime.defmeth.shared.DefMethTest;50import vm.runtime.defmeth.shared.executor.TestExecutor;5152import static jdk.internal.org.objectweb.asm.Opcodes.*;53import static vm.runtime.defmeth.shared.ExecutionMode.*;5455/**56* Basic tests on some of the assertions from JVMS.57*/58public class BasicTest extends DefMethTest {5960public static void main(String[] args) {61DefMethTest.runTest(BasicTest.class,62/* majorVer */ Set.of(MIN_MAJOR_VER, MAX_MAJOR_VER),63/* flags */ Set.of(0, ACC_SYNCHRONIZED),64/* redefine */ Set.of(false, true),65/* execMode */ Set.of(DIRECT, REFLECTION, INVOKE_EXACT, INVOKE_GENERIC, INVOKE_WITH_ARGS, INDY));66}6768/*69* JVMS 6.5 invokevirtual70*71* ...72*73* Runtime Exceptions74*75* Otherwise, if the resolved method is not signature polymorphic:76*77*/7879/*80* ...81*82* If the resolved method is declared in an interface and the class of83* objectref does not implement the resolved interface, invokevirtual throws84* an IncompatibleClassChangeError.85*/86public void testInterfaceNotImplemented(TestBuilder b) {87Interface I = b.intf("I")88.defaultMethod("m", "()V").emptyBody().build()89.build();9091ConcreteClass C = b.clazz("C").build();9293Class expectedClass;94if (factory.getExecutionMode().equals("REFLECTION")) {95expectedClass = IllegalArgumentException.class;96} else if (factory.getExecutionMode().equals("INVOKE_WITH_ARGS")) {97// Notes from JDK-8029926 which details reasons behind CCE.98// The code below demonstrates the use of a MethodHandle99// of kind REF_invokeInterface pointing to method I.m.100// Because 'invoke' is called, this MethodHandle is effectively101// wrapped in the type adaptations necessary to accept a C102// as the first argument. ***Before we even get to the point103// of the invokeinterface call to I.m***, the adaptation104// code must run, and that is where the ClassCastException occurs.105// This exception can be thrown from code that is cleanly106// compiled and does no bytecode generation, so an ICCE would107// be inappropriate since no classes are changed.108expectedClass = ClassCastException.class;109} else {110expectedClass = IncompatibleClassChangeError.class;111}112113b.test().callSite(I, C, "m", "()V").throws_(expectedClass).done();114}115116/*117* ...118*119* Otherwise, if no method matching the resolved name and descriptor is120* selected, invokevirtual throws an NoSuchMethodError.121*122* ...123*/124public void testNoMatch(TestBuilder b) {125Interface I = b.intf("I")126.defaultMethod("m", "(Ljava/lang/Object;)V").emptyBody().build()127.build();128129ConcreteClass C = b.clazz("C").implement(I).build();130131b.test().callSite(C, C, "m", "()I").throws_(NoSuchMethodError.class).done()132.test().callSite(C, C, "m1", "()V").throws_(NoSuchMethodError.class).done()133.test().callSite(C, C, "m", "(I)V").throws_(NoSuchMethodError.class).done();134}135136/*137* ...138*139* 8025604: Updated specification text for both 5.4.3.3 and 5.4.4.4140* "Otherwise, if any superinterface of C declares a method with the name and141* descriptor specified by the method reference that has set neither142* its ACC_PRIVATE flag nor its ACC_STATIC flag, one of these is arbitrarily143* chosen and method lookup succeeds."144* If method lookup fails, method resolution throws a NoSuchMethodError145*146* ...147*/148public void testNonPublic(TestBuilder b) {149Interface I = b.intf("I")150.defaultMethod("m1", "()V").private_().emptyBody().build()151.defaultMethod("m2", "()I").private_().returns(1).build()152.build();153154ConcreteClass C = b.clazz("C").implement(I).build();155156b.test().callSite(C, C, "m1", "()V").throws_(NoSuchMethodError.class).done()157.test().callSite(C, C, "m2", "()I").throws_(NoSuchMethodError.class).done();158}159160/*161* Default method override attempt w/ non-public concrete method.162* Private methods never override any other method.163*164* interface I { int m() default { returns 1; } }165* class C/D/E implements I {166* [private/protected/package-private]167* int m() { returns 2;}168* }169*170*/171public void testNonPublicOverride(TestBuilder b) {172Interface I = b.intf("I")173.defaultMethod("m", "()I").returns(1).build()174.build();175176ConcreteClass C = b.clazz("C").implement(I)177.concreteMethod("m", "()I").private_().returns(2).build()178.build();179180ConcreteClass D = b.clazz("D").implement(I)181.concreteMethod("m", "()I").protected_().returns(2).build()182.build();183184ConcreteClass E = b.clazz("E").implement(I)185.concreteMethod("m", "()I").package_private().returns(2).build()186.build();187188b.test().callSite(I, C, "m", "()I").returns(1).done()189.test().callSite(I, D, "m", "()I").throws_(IllegalAccessError.class).done()190.test().callSite(I, E, "m", "()I").throws_(IllegalAccessError.class).done();191}192193194/**195* interface I {196* static { throw new RE(); }197* public default void m() {}198* }199*200* class C implements I {}201*202* TEST: C c = new C(); ==> ExceptionInInitializerError203* Static initialization of class C will trigger204* I's static initialization due to I's default method.205*/206public void testStaticInit(TestBuilder b) {207Interface I = b.intf("I")208.defaultMethod("<clinit>", "()V")209.flags(ACC_STATIC)210.throw_(RuntimeException.class)211.build()212213.defaultMethod("m", "()V")214.emptyBody().build()215.build();216217ConcreteClass C = b.clazz("C").implement(I).build();218219boolean isReflectionMode = factory.getExecutionMode().equals("REFLECTION");220Class expectedError = isReflectionMode ? RuntimeException.class221: ExceptionInInitializerError.class;222223b.test().new_(C).throws_(expectedError).done();224}225226/**227* interface I {228* static { throw new RE(); }229* private default void m() {}230* }231*232* class C implements I {}233*234* TEST: C c = new C(); ==> ExceptionInInitializerError235* Static initialization of class C will trigger236* I's static initialization due to I's private concrete method.237*/238public void testStaticInitPrivate(TestBuilder b) {239Interface I = b.intf("I")240.defaultMethod("<clinit>", "()V")241.flags(ACC_STATIC)242.throw_(RuntimeException.class)243.build()244245.defaultMethod("m", "()V")246.flags(ACC_PRIVATE)247.emptyBody().build()248.build();249250ConcreteClass C = b.clazz("C").implement(I).build();251252boolean isReflectionMode = factory.getExecutionMode().equals("REFLECTION");253Class expectedError = isReflectionMode ? RuntimeException.class254: ExceptionInInitializerError.class;255256b.test().new_(C).throws_(expectedError).done();257}258259/**260* interface I {261* static { throw new RE()}262* }263* interface J {264* public default int m() { return 1}265*266* class C implements I,J {}267*268* TEST: C c = new C()269* c.m() returns 1270* Static initialization of class C will not trigger271* I's static initialization since I has no concrete methods.272*/273public void testNotStaticInitNoDefault(TestBuilder b) {274Interface I = b.intf("I")275.defaultMethod("<clinit>", "()V")276.flags(ACC_STATIC)277.throw_(RuntimeException.class)278.build()279.build();280281Interface J = b.intf("J")282.defaultMethod("m", "()I")283.returns(1).build()284.build();285286ConcreteClass C = b.clazz("C").implement(I,J).build();287288b.test().callSite(C, C, "m", "()I").returns(1).done();289}290291/*292* Example A.10293*294* Let L1 and L2 be class loaders with different interpretations of the type "A".295*296* Loaded by L1:297* public interface I { public default A m() { return null; } }298*299* Loaded by L2:300* public class C implements I {}301*302* TEST: I o = new C(); o.m() ==> LinkageError;303* TEST: C o = new C(); o.m() ==> LinkageError;304*/305// disabling this test for REFLECTION and INVOKE for now until306// loader constraint issue associated with those modes has been resolved307@NotApplicableFor(modes = { REFLECTION, INVOKE_WITH_ARGS, INVOKE_EXACT, INVOKE_GENERIC, INDY })308public void testLoaderConstraint() {309TestBuilder b = factory.getBuilder();310ConcreteClass A = b.clazz("A").build();311312Interface I = b.intf("I")313.defaultMethod("m", "()LA;").returnsNewInstance(A).build()314.build();315316ConcreteClass C = b.clazz("C").implement(I).build();317318b.test().callSite(I, C, "m", "()LA;").throws_(LinkageError.class).done();319b.test().callSite(C, C, "m", "()LA;").throws_(LinkageError.class).done();320321TestExecutor executor = b.prepare(new TestBuilder.LoaderConstructor() {322@Override323public MemoryClassLoader construct(Map<String, byte[]> classFiles) {324final byte[] cfI = classFiles.get("I");325final byte[] cfC = classFiles.get("C");326final byte[] cfA = classFiles.get("A");327final byte[] cfT1 = classFiles.get("Test1_I_C_m");328final byte[] cfT2 = classFiles.get("Test2_C_C_m");329330final ClassLoader l1 = new ClassLoader() {331@Override332protected Class<?> findClass(String name) throws ClassNotFoundException {333switch (name) {334case "I":335return defineClass(name, cfI, 0, cfI.length);336case "A":337return defineClass(name, cfA, 0, cfA.length);338default:339throw new ClassNotFoundException(name);340}341}342};343344final MemoryClassLoader l2 = new MemoryClassLoader(classFiles) {345@Override346public Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {347if ("I".equals(name)) {348return l1.loadClass(name);349} else {350return super.loadClass(name, resolve);351}352}353};354355try {356// Need to preload classes, otherwise A will be resolved in the same loader357l1.loadClass("A"); l1.loadClass("I");358l2.loadClass("A"); l2.loadClass("C");359} catch (ClassNotFoundException e) {360throw new TestFailure(e);361}362363return l2;364}365});366367executor.run();368}369}370371372