Path: blob/master/test/hotspot/jtreg/vmTestbase/vm/runtime/defmeth/ConflictingDefaultsTest.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.ConflictingDefaultsTest37*/38package vm.runtime.defmeth;3940import java.util.Set;4142import vm.runtime.defmeth.shared.DefMethTest;43import vm.runtime.defmeth.shared.annotation.NotApplicableFor;44import vm.runtime.defmeth.shared.builder.TestBuilder;45import vm.runtime.defmeth.shared.data.*;4647import static jdk.internal.org.objectweb.asm.Opcodes.ACC_SYNCHRONIZED;48import static vm.runtime.defmeth.shared.data.method.body.CallMethod.Invoke.*;49import static vm.runtime.defmeth.shared.data.method.body.CallMethod.IndexbyteOp.*;50import static vm.runtime.defmeth.shared.ExecutionMode.*;5152/**53* Tests on conflicting defaults.54*55* It is allowable to inherit a default through multiple paths (such as56* through a diamond-shaped interface hierarchy), but the resolution procedure57* is looking for a unique, most specific default-providing interface.58*59* If one default shadows another (where a subinterface provides a different60* default for an extension method declared in a superinterface), then the less61* specific interface is pruned from consideration no matter where it appears62* in the inheritance hierarchy. If two or more extended interfaces provide63* default implementations, and one is not a superinterface of the other, then64* neither is used and a linkage exception is thrown indicating conflicting65* default implementations.66*/67public class ConflictingDefaultsTest extends DefMethTest {68public static void main(String[] args) {69DefMethTest.runTest(ConflictingDefaultsTest.class,70/* majorVer */ Set.of(MIN_MAJOR_VER, MAX_MAJOR_VER),71/* flags */ Set.of(0, ACC_SYNCHRONIZED),72/* redefine */ Set.of(false, true),73/* execMode */ Set.of(DIRECT, REFLECTION, INVOKE_EXACT, INVOKE_GENERIC, INVOKE_WITH_ARGS, INDY));74}7576/*77* Conflict78*79* interface I { int m() default { return 1; } }80* interface J { int m() default { return 2; } }81* class C implements I, J {}82*83* TEST: C c = new C(); c.m() ==> ICCE84*/85public void testConflict(TestBuilder b) {86Interface I = b.intf("I")87.defaultMethod("m", "()I").returns(1).build()88.build();8990Interface J = b.intf("J")91.defaultMethod("m", "()I").returns(2).build()92.build();9394ConcreteClass C = b.clazz("C").implement(I,J).build();9596b.test().callSite(C, C, "m","()I")97.throws_(IncompatibleClassChangeError.class)98.done();99}100101/*102* Maximally-specific Default (0.6.3 spec change)103*104* interface I { int m(); }105* interface J { int m() default { return 2; } }106* class C implements I, J {}107*108* TEST: C c = new C(); c.m() return 2109*/110public void testMaximallySpecificDefault(TestBuilder b) {111Interface I = b.intf("I")112.abstractMethod("m", "()I").build()113.build();114115Interface J = b.intf("J")116.defaultMethod("m", "()I").returns(2).build()117.build();118119ConcreteClass C = b.clazz("C").implement(I,J).build();120121b.test().callSite(C, C, "m","()I")122.returns(2)123.done();124}125126/*127* Reabstract128*129* interface I { int m() default { return 1; } }130* interface J extends I { int m(); }131* class C implements J {}132*133* TEST: C c = new C(); c.m() ==> AME134*/135public void testReabstract(TestBuilder b) {136Interface I = b.intf("I")137.defaultMethod("m", "()I").returns(1).build()138.build();139140Interface J = b.intf("J").extend(I)141.abstractMethod("m", "()I").build()142.build();143144ConcreteClass C = b.clazz("C").implement(J).build();145146b.test().callSite(C, C, "m","()I")147.throws_(AbstractMethodError.class)148.done();149}150151/*152* Reabstract2153*154* interface I { int m() default { return 1; } }155* interface J extends I { int m(); }156* class C implements J {}157* class D extends C { callSuper C.m}158*159* TEST: C c = new C(); c.m() ==> AME160* TEST: J j = new C(); j.m() ==> AME161* TEST: I i = new C(); i.m() ==> AME162* TEST: D d = new D(); d.m() ==> callSuper C.m ==> AME163*/164public void testReabstract2(TestBuilder b) {165Interface I = b.intf("I")166.defaultMethod("m", "()I").returns(1).build()167.build();168169Interface J = b.intf("J").extend(I)170.abstractMethod("m", "()I").build()171.build();172173ConcreteClass C = b.clazz("C").implement(J).build();174ConcreteClass D = b.clazz("D").extend(C)175.concreteMethod("m", "()I").callSuper(C, "m", "()I").build()176.build();177178b.test().callSite(C, C, "m","()I")179.throws_(AbstractMethodError.class)180.done()181.test().callSite(J, C, "m","()I")182.throws_(AbstractMethodError.class)183.done()184.test().callSite(I, C, "m","()I")185.throws_(AbstractMethodError.class)186.done()187.test().callSite(D, D, "m","()I")188.throws_(AbstractMethodError.class)189.done();190}191192/*193* ReabstractConflictingDefaults194*195* interface I { int m() default { return 1; } }196* interface J { int m() default { return 2; } }197* interface K extends I,J { int m(); }198* class A implements I,J {}199* class C extends A implements K {}200*201* TEST: A c = new C(); c.m() ==> AME202*/203public void testReabstractConflictingDefaults(TestBuilder b) {204Interface I = b.intf("I")205.defaultMethod("m", "()I").returns(1).build()206.build();207208Interface J = b.intf("J")209.defaultMethod("m", "()I").returns(2).build()210.build();211212Interface K = b.intf("K").extend(I,J)213.abstractMethod("m", "()I").build()214.build();215216ConcreteClass A = b.clazz("A").implement(I,J).build();217ConcreteClass C = b.clazz("C").extend(A).implement(K).build();218219b.test().callSite(A, C, "m","()I")220.throws_(AbstractMethodError.class)221.done();222}223224225/*226* ReabstractConflictingDefaultsInvokeInterface227*228* interface I { int m() default { return 1; } }229* interface J { int m() default { return 2; } }230* interface K extends I,J { int m(); }231* interface L extends K { }232* class A implements I,J {}233* class C extends A implements K {}234* class D extends C implements L {}235*236* TEST: I i = new A(); i.m() ==> ICCE237* TEST: K k = new C(); k.m() ==> AME238* TEST: L l = new D(); l.m() ==> AME239*/240public void testReabstractConflictingDefaultsInvokeInterface(TestBuilder b) {241Interface I = b.intf("I")242.defaultMethod("m", "()I").returns(1).build()243.build();244245Interface J = b.intf("J")246.defaultMethod("m", "()I").returns(2).build()247.build();248249Interface K = b.intf("K").extend(I,J)250.abstractMethod("m", "()I").build()251.build();252253Interface L = b.intf("L").extend(K)254.build();255256ConcreteClass A = b.clazz("A").implement(I,J).build();257ConcreteClass C = b.clazz("C").extend(A).implement(K).build();258ConcreteClass D = b.clazz("D").extend(C).implement(L).build();259260b.test().callSite(I, A, "m","()I")261.throws_(IncompatibleClassChangeError.class)262.done()263.test().callSite(K, C, "m","()I")264.throws_(AbstractMethodError.class)265.done()266.test().callSite(L, D, "m","()I")267.throws_(AbstractMethodError.class)268.done();269}270271/*272* ReabstractConflictingDefaultsSuper273*274* interface I { int m() default { return 1; } }275* interface J { int m() default { return 2; } }276* interface K extends I,J { int m(); }277* interface L extends K { }278* class A implements I,J {}279* class C extends A implements K {}280* class D extends C implements L {int m() {callSuper A.m }281*282* TEST: I i = new A(); i.m() ==> ICCE283* TEST: K k = new C(); CallSuper k.m() ==> AME284* TEST: L l = new D(); l.m() ==> AME285*/286public void testReabstractConflictingDefaultsSuper(TestBuilder b) {287Interface I = b.intf("I")288.defaultMethod("m", "()I").returns(1).build()289.build();290291Interface J = b.intf("J")292.defaultMethod("m", "()I").returns(2).build()293.build();294295Interface K = b.intf("K").extend(I,J)296.abstractMethod("m", "()I").build()297.build();298299Interface L = b.intf("L").extend(K)300.build();301302ConcreteClass A = b.clazz("A").implement(I,J).build();303ConcreteClass C = b.clazz("C").extend(A).implement(K).build();304ConcreteClass D = b.clazz("D").extend(C).implement(L)305.concreteMethod("m", "()I").callSuper(A, "m", "()I").build()306.build();307308b.test().callSite(I, A, "m","()I")309.throws_(IncompatibleClassChangeError.class)310.done()311.test().callSite(L, D, "m","()I")312.throws_(AbstractMethodError.class)313.done();314}315316/*317* testReabstractResolveMethod00705m2318*319* Test case for JDK-8027804: JCK resolveMethod test fails expecting AME320*321* This test is an extension of the JCK test resolveMethod00705m2322* with additional invoke* bytecodes specified for testing purposes.323*324* interface I { int m() default { return 1; } }325* interface J implements I { int m(); }326* class A implements J,I {}327* class C extends A {}328*329* TEST: A a = new C(); a.m() ==> AME (invokevirtual)330* C c = new C(); c.m() ==> AME (invokevirtual)331* J j = new C(); j.m() ==> AME (invokeinterface)332* I i = new C(); i.m() ==> AME (invokeinterface)333* c.test_Cmethod_ISMR(); c.super.m() ==> AME (invokespecial MR)334* a.test_Amethod_ISIMR(); j.super.m() ==> AME (invokespecial IMR)335*336* For ver > 49, error will be AME337* For ver = 49, error will be VE338*/339340@NotApplicableFor(modes = { REDEFINITION }) // Can't redefine a class that gets error during loading341public void testReabstractResolveMethod00705m2(TestBuilder b) {342Interface I = b.intf("I")343.defaultMethod("m", "()I").returns(1).build()344.build();345346Interface J = b.intf("J").extend(I)347.abstractMethod("m", "()I").build()348.build();349350ConcreteClass A = b.clazz("A").implement(J,I)351.concreteMethod("test_Amethod_ISIMR", "()V")352.invoke(SPECIAL, b.clazzByName("J"), b.clazzByName("A"),353"m", "()I", INTERFACEMETHODREF)354.build()355.build();356357ConcreteClass C = b.clazz("C").extend(A)358.concreteMethod("test_Cmethod_ISMR", "()V")359.invoke(SPECIAL, b.clazzByName("C"), b.clazzByName("C"),360"m", "()I", CALLSITE)361.build()362.build();363364Class expectedError1, expectedError2;365if (factory.getVer() >=52) {366expectedError1 = expectedError2 = AbstractMethodError.class;367} else {368expectedError1 = expectedError2 = VerifyError.class;369}370371b.test().callSite(A, C, "m", "()I")372.throws_(expectedError2)373.done()374.test().callSite(C, C, "m", "()I")375.throws_(expectedError2)376.done()377.test().callSite(J, C, "m", "()I")378.throws_(expectedError1)379.done()380.test().callSite(I, C, "m", "()I")381.throws_(expectedError1)382.done()383.test().callSite(C, C, "test_Cmethod_ISMR", "()V")384.throws_(expectedError2)385.done()386.test().callSite(A, C, "test_Amethod_ISIMR", "()V")387.throws_(expectedError2)388.done();389}390391/*392* Shadow393*394* interface I { int m() default { return 1; } }395* interface J extends I { int m() default { return 2; } }396* class C implements J {}397*398* TEST: [I|J|C] c = new C(); c.m() == 2;399*/400public void testShadow(TestBuilder b) {401Interface I = b.intf("I")402.defaultMethod("m", "()I").returns(1).build()403.build();404405Interface J = b.intf("J").extend(I)406.defaultMethod("m", "()I").returns(2).build()407.build();408409ConcreteClass C = b.clazz("C").implement(J).build();410411b.test().callSite(I, C, "m","()I")412.returns(2)413.done()414.test()415.callSite(J, C, "m","()I")416.returns(2)417.done()418.test()419.callSite(C, C, "m","()I")420.returns(2)421.done();422}423424/*425* Disqualified426*427* interface I { int m() default { return 1; } }428* interface J extends I { int m() default { return 2; } }429* class C implements I, J {}430*431* TEST: [I|J|C] c = new C(); c.m() == 2;432*/433public void testDisqualified(TestBuilder b) {434Interface I = b.intf("I")435.defaultMethod("m", "()I").returns(1).build()436.build();437438Interface J = b.intf("J").extend(I)439.defaultMethod("m", "()I").returns(2).build()440.build();441442ConcreteClass C = b.clazz("C").implement(I,J).build();443444b.test()445.callSite(I, C, "m","()I")446.returns(2)447.done()448.test()449.callSite(J, C, "m","()I")450.returns(2)451.done()452.test()453.callSite(C, C, "m","()I")454.returns(2)455.done();456}457458/*459* Mixed arity460*461* interface I { int m() default { return 1; } }462* interface J { int m(int i) default { return 2; } }463* class C implements I, J {}464*465* TEST: I i = new C(); i.m() == 1; i.m(0) ==> NSME466* TEST: J j = new C(); j.m() ==> NSME; j.m(0) == 2467* TEST: C c = new C(); c.m() == 1; c.m(0) == 2468*/469public void testMixedArity1(TestBuilder b) {470Interface I = b.intf("I")471.defaultMethod("m", "()I").returns(1).build()472.build();473474Interface J = b.intf("J")475.defaultMethod("m", "(I)I").returns(2).build()476.build();477478ConcreteClass C = b.clazz("C").implement(I,J).build();479480// I i = new C(); ...481b.test()482.callSite(I, C, "m","()I")483.returns(1)484.done()485.test()486.callSite(I, C, "m","(I)I")487.params(0)488.throws_(NoSuchMethodError.class)489.done()490491// J j = new C(); ...492.test()493.callSite(J, C, "m","()I")494.throws_(NoSuchMethodError.class)495.done()496.test()497.callSite(J, C, "m","(I)I")498.params(0)499.returns(2)500.done()501502// C c = new C(); ...503.test()504.callSite(C, C, "m","()I")505.returns(1)506.done()507.test()508.callSite(C, C, "m","(I)I")509.params(0)510.returns(2)511.done();512}513514/*515* Mixed arity516*517* interface I { int m() default { return 1; } }518* interface J { int m() default { return 2; } }519* class C implements I, J { int m(int i) { return 3; }}520*521* TEST: I i = new C(); i.m() ==> ICCE522* TEST: J j = new C(); j.m() ==> ICCE523* TEST: C c = new C(); c.m() ==> ICCE; c.m(0) == 3524*/525public void testMixedArity2(TestBuilder b) {526Interface I = b.intf("I")527.defaultMethod("m", "()I").returns(1).build()528.build();529530Interface J = b.intf("J")531.defaultMethod("m", "()I").returns(2).build()532.build();533534ConcreteClass C = b.clazz("C").implement(I,J)535.concreteMethod("m", "(I)I").returns(3).build()536.build();537538// I i = new C(); ...539b.test()540.callSite(I, C, "m","()I")541.throws_(IncompatibleClassChangeError.class)542.done()543544// J j = new C(); ...545.test()546.callSite(J, C, "m","()I")547.throws_(IncompatibleClassChangeError.class)548.done()549550// C c = new C(); ...551.test()552.callSite(C, C, "m","()I")553.throws_(IncompatibleClassChangeError.class)554.done()555.test()556.callSite(C, C, "m","(I)I")557.params(0)558.returns(3)559.done();560}561}562563564