Path: blob/master/test/hotspot/jtreg/vmTestbase/vm/runtime/defmeth/PrivateMethodsTest.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.PrivateMethodsTest37*/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* Scenarios on private methods in interfaces.54*/55public class PrivateMethodsTest extends DefMethTest {5657public static void main(String[] args) {58DefMethTest.runTest(PrivateMethodsTest.class,59/* majorVer */ Set.of(MIN_MAJOR_VER, MAX_MAJOR_VER),60/* flags */ Set.of(0, ACC_SYNCHRONIZED),61/* redefine */ Set.of(false, true),62/* execMode */ Set.of(DIRECT, REFLECTION, INVOKE_EXACT, INVOKE_GENERIC, INVOKE_WITH_ARGS, INDY));63}6465// invokevirtual & invokeinterface from same/subintf66// Spec change July 2013 to not allow invokevirtual or invokeinterface67// to even see an interface private method68// Throw ICCE if method resolution returns interface private method6970// Spec change JDK 11 - invokeinterface can be used for private interface71// methods and is now the preferred invocation bytecode - so no ICCE.72// Private methods are skipped during selection unless the resolved method73// is private.74// This change is not dependent on the classfile version.7576// Note on reflection testing:77// Reflection is only used for the initial callsite, which is not always78// the method of interest. For example where a default method m() calls79// the private interface method privateM(). It is the latter call we are80// really testing, but it is the call of the default method that occurs81// via reflection.8283/*84* testPrivateInvokeVirtual85*86* interface I {87* private int privateM() { return 1; }88* default public int m() { return (I)this.privateM(); } // invokevirtual89* }90* class C implements I {}91*92* TEST: I o = new C(); o.m()I throws VerifyError93* TEST: C o = new C(); o.m()I throws VerifyError94*/95@NotApplicableFor(modes = { REDEFINITION }) // Can't redefine a class that gets error during loading96public void testPrivateInvokeVirtual(TestBuilder b) {97Interface I = b.intf("I")98.defaultMethod("privateM", "()I")99.private_().returns(1).build()100101// force an invokevirtual of an IMR to test verification code102.defaultMethod("m", "()I")103.invoke(VIRTUAL, b.intfByName("I"), null, "privateM", "()I", INTERFACEMETHODREF).build()104.build();105106ConcreteClass C = b.clazz("C").implement(I).build();107108b.test().callSite(I, C, "m", "()I").throws_(VerifyError.class).done()109.test().callSite(C, C, "m", "()I").throws_(VerifyError.class).done();110}111112/*113* testPrivateInvokeIntf114*115* interface I {116* private int privateM() { return 1; }117* default public int m() { return (I)this.privateM(); } // invokeinterface118* }119* class C implements I {}120*121* TEST: I o = new C(); o.m()I returns 1122* TEST: C o = new C(); o.m()I returns 1123*/124public void testPrivateInvokeIntf(TestBuilder b) {125Interface I = b.intf("I")126.defaultMethod("privateM", "()I")127.private_().returns(1).build()128.defaultMethod("m", "()I")129.invoke(INTERFACE, b.intfByName("I"), null, "privateM", "()I", CALLSITE).build()130.build();131132ConcreteClass C = b.clazz("C").implement(I).build();133134b.test().callSite(I, C, "m", "()I").returns(1).done()135.test().callSite(C, C, "m", "()I").returns(1).done();136}137138/*139* testPrivateInvokeStatic140*141* interface I {142* private int privateM() { return 1; }143* default public int m() { return I.privateM(); } // invokestatic144* }145* class C implements I {}146*147* TEST: I o = new C(); o.m()I throws IncompatibleClassChangeError148* TEST: C o = new C(); o.m()I throws IncompatibleClassChangeError149*/150public void testPrivateInvokeStatic(TestBuilder b) {151Interface I = b.intf("I")152.defaultMethod("privateM", "()I")153.private_().returns(1).build()154.defaultMethod("m", "()I")155.invoke(STATIC, b.intfByName("I"), null, "privateM", "()I", CALLSITE).build()156.build();157158ConcreteClass C = b.clazz("C").implement(I).build();159160b.test().callSite(I, C, "m", "()I").throws_(IncompatibleClassChangeError.class).done()161.test().callSite(C, C, "m", "()I").throws_(IncompatibleClassChangeError.class).done();162}163164// call from another default method in the same interface165/*166* testPrivateCallSameClass167*168* interface I {169* private privateM()I { return 1; }170* default public int m() { return I.super.privateM(); } // invokespecial171* }172* class C implements I {}173*174* TEST: { I o = new C(); o.m()I == 1; }175* TEST: { C o = new C(); o.m()I == 1; }176*/177public void testPrivateCallSameClass(TestBuilder b) {178Interface I = b.intf("I")179.defaultMethod("privateM", "()I")180.private_().returns(1).build()181.defaultMethod("m", "()I")182.invokeSpecial(b.intfByName("I"), "privateM", "()I").build()183.build();184185ConcreteClass C = b.clazz("C").implement(I).build();186187b.test().callSite(I, C, "m", "()I").returns(1).done()188.test().callSite(C, C, "m", "()I").returns(1).done();189}190191/*192* testPrivateCallSubIntf193*194* Attempt to call from subinterface fails195196* interface I {197* private privateM()I { return 1; }198* }199* J, K, L use invokespecial200* interface J extends I {201* default public int m() { return I.super.privateM(); }202* }203* interface K extends I {204* default public int m() { return K.super.privateM(); }205* }206* interface L extends J {207* default public int m() { return I.super.privateM(); }208* }209* class C implements J {}210* class D implements K {}211* class E implements L {}212*213* TEST: { J o = new C(); o.m()I throws IAE; }214* TEST: { C o = new C(); o.m()I throws IAE; }215* TEST: { K o = new D(); o.m()I throws NSME; } // does not see216* TEST: { D o = new D(); o.m()I throws NSME; }217* TEST: { L o = new E(); o.m()I throws VerifyError; } // VerifyError intfmethodref218* TEST: { E o = new E(); o.m()I throws VerifyError; }219*/220@NotApplicableFor(modes = { REDEFINITION }) // Can't redefine a class that gets error during loading221public void testPrivateCallSubIntf(TestBuilder b) {222Interface I = b.intf("I")223.defaultMethod("privateM", "()I")224.private_().returns(1).build()225.build();226227Interface J = b.intf("J").extend(I)228.defaultMethod("m", "()I")229.invokeSpecial(I, "privateM", "()I").build()230.build();231232Interface K = b.intf("K").extend(J)233.defaultMethod("m", "()I")234.invokeSpecial(b.intfByName("K"), "privateM", "()I").build()235.build();236237// L.privateM -> J -> L (I.privateM call)238Interface L = b.intf("L").extend(J)239.defaultMethod("m", "()I")240.invokeSpecial(I, "privateM", "()I").build()241.build();242243ConcreteClass C = b.clazz("C").implement(J).build();244245ConcreteClass D = b.clazz("D").implement(K).build();246247ConcreteClass E = b.clazz("E").implement(L).build();248249b.test().callSite(J, C, "m", "()I").throws_(IllegalAccessError.class).done()250.test().callSite(C, C, "m", "()I").throws_(IllegalAccessError.class).done()251252.test().callSite(K, D, "m", "()I").throws_(NoSuchMethodError.class).done()253.test().callSite(D, D, "m", "()I").throws_(NoSuchMethodError.class).done()254255.test().callSite(L, E, "m", "()I").throws_(VerifyError.class).done()256.test().callSite(E, E, "m", "()I").throws_(VerifyError.class).done();257}258259/*260* Attempt to call from subclass fails261*262* interface I {263* private privateM()I { return 1; }264* }265* class C implements I {266* public int m() { return I.super.privateM(); }267* }268* class D extends C {269* public int m() { return I.super.privateM(); }270* }271* class E extends C {272* public int m() { return C.super.privateM(); }273* }274*275* TEST: { C o = new C(); o.m()I throws IllegalAccessError (or VerifyError) }276* TEST: { D o = new D(); o.m()I throws VerifyError }277* TEST: { E o = new E(); o.m()I throws NoSuchMethodError (or VerifyError); }278*/279@NotApplicableFor(modes = { REDEFINITION }) // Can't redefine a class that gets error during loading280public void testPrivateCallImplClass(TestBuilder b) {281Interface I = b.intf("I")282.defaultMethod("privateM", "()I")283.private_().returns(1).build()284.build();285286ConcreteClass C = b.clazz("C").implement(I)287.concreteMethod("m", "()I")288.invokeSpecial(I, "privateM", "()I").build()289.build();290291ConcreteClass D = b.clazz("D").extend(C)292.concreteMethod("m", "()I")293.invokeSpecial(I, "privateM", "()I").build()294.build();295296ConcreteClass E = b.clazz("E").extend(C)297.concreteMethod("m", "()I")298.invokeSpecial(C, "privateM", "()I").build()299.build();300301Class eeExpectedClass;302Class ccExpectedClass;303if (factory.getVer() >= 52) {304eeExpectedClass = NoSuchMethodError.class;305ccExpectedClass = IllegalAccessError.class;306} else {307// The test gets a VerifyError in this case due to an308// invokespecial IMR bytecode. This was not allowed309// until class file version 52. (See 8030249.)310eeExpectedClass = VerifyError.class;311ccExpectedClass = VerifyError.class;312}313b.test().callSite(C, C, "m", "()I").throws_(ccExpectedClass).done()314.test().callSite(D, D, "m", "()I").throws_(VerifyError.class).done()315.test().callSite(E, E, "m", "()I").throws_(eeExpectedClass).done();316}317318// doesn't participate in default method analysis319// method overriding320321/*322* testPrivate323*324* interface I {325* private int m() { return 1; }326* }327* class C implements I {}328*329* TEST: { I o = new C(); o.m()I throws IllegalAccessError; }330* TEST: { C o = new C(); o.m()I throws NoSuchMethodError; }331*/332public void testPrivate(TestBuilder b) {333Interface I = b.intf("I")334.defaultMethod("m", "()I")335.private_().returns(1).build()336.build();337338ConcreteClass C = b.clazz("C").implement(I).build();339340b.test().privateCallSite(I, C, "m", "()I").throws_(IllegalAccessError.class).done()341.test(). callSite(C, C, "m", "()I").throws_(NoSuchMethodError.class).done();342}343344/*345* testPrivateVsConcrete346*347* interface I {348* private int m() { return 1; }349* }350* class C implements I {351* public int m() { return 2; }352* }353*354* TEST: { I o = new C(); o.m()I == IllegalAccessError; }355* TEST: { C o = new C(); o.m()I == 2; }356*/357public void testPrivateVsConcrete(TestBuilder b) {358Interface I = b.intf("I")359.defaultMethod("m", "()I")360.private_().returns(1).build()361.build();362363ConcreteClass C = b.clazz("C").implement(I)364.concreteMethod("m", "()I").returns(2).build()365.build();366367b.test().privateCallSite(I, C, "m", "()I").throws_(IllegalAccessError.class).done()368.test(). callSite(C, C, "m", "()I").returns(2).done();369}370371/*372* testPublicOverridePrivate373*374* interface I {375* private int m() { return 1; }376* }377* interface J extends I {378* default public int m() { return 2; }379* }380* class C implements J {}381*382* TEST: { I o = new C(); o.m()I throws IllegalAccessError; }383* TEST: { J o = new C(); o.m()I == 2; }384* TEST: { C o = new C(); o.m()I == 2; }385*/386public void testPublicOverridePrivate(TestBuilder b) {387Interface I = b.intf("I")388.defaultMethod("m", "()I")389.private_().returns(1).build()390.build();391392Interface J = b.intf("J").extend(I)393.defaultMethod("m", "()I")394.returns(2).build()395.build();396397ConcreteClass C = b.clazz("C").implement(J).build();398399b.test().privateCallSite(I, C, "m", "()I").throws_(IllegalAccessError.class).done()400.test(). callSite(J, C, "m", "()I").returns(2).done()401.test(). callSite(C, C, "m", "()I").returns(2).done();402}403404/*405* testPrivateOverrideDefault406*407* interface I {408* default public int m() { return 1; }409* }410* interface J extends I {411* private int m() { return 2; }412* }413* class C implements J {}414*415* TEST: { I o = new C(); o.m()I == 1; }416* TEST: { J o = new C(); o.m()I == IllegalAccessError; } II J.m priv417* TEST: { C o = new C(); o.m()I == 1; }418*/419public void testPrivateOverrideDefault(TestBuilder b) {420Interface I = b.intf("I")421.defaultMethod("m", "()I")422.returns(1).build()423.build();424425Interface J = b.intf("J").extend(I)426.defaultMethod("m", "()I")427.private_().returns(2).build()428.build();429430ConcreteClass C = b.clazz("C").implement(J).build();431432b.test().callSite(I, C, "m", "()I").returns(1).done()433.test().privateCallSite(J, C, "m", "()I").throws_(IllegalAccessError.class).done()434.test().callSite(C, C, "m", "()I").returns(1).done();435}436437/*438* testPrivateReabstract439*440* interface I {441* private int m() { return 1; }442* }443* interface J extends I {444* abstract public int m();445* }446* class C implements J {}447*448* TEST: { I o = new C(); o.m()I throws IllegalAccessError; } II I.m449* TEST: { J o = new C(); o.m()I throws java/lang/AbstractMethodError; }450* TEST: { C o = new C(); o.m()I throws java/lang/AbstractMethodError; }451*/452public void testPrivateReabstract(TestBuilder b) {453Interface I = b.intf("I")454.defaultMethod("m", "()I")455.private_().returns(1).build()456.build();457458Interface J = b.intf("J").extend(I)459.abstractMethod("m", "()I").build()460.build();461462ConcreteClass C = b.clazz("C").implement(J).build();463464b.test().privateCallSite(I, C, "m", "()I").throws_(IllegalAccessError.class).done()465.test(). callSite(J, C, "m", "()I").throws_(AbstractMethodError.class).done()466.test(). callSite(C, C, "m", "()I").throws_(AbstractMethodError.class).done();467}468469/*470* testPrivateOverrideAbstract471*472* interface I {473* abstract public int m();474* }475* interface J extends I {476* private int m() { return 1; }477* }478* class C implements J {}479*480* TEST: { I o = new C(); o.m()I throws AbstractMethodError }481* TEST: { J o = new C(); o.m()I throws IllegalAccessError }482* TEST: { C o = new C(); o.m()I throws AbstractMethodError }483*/484public void testPrivateOverrideAbstract(TestBuilder b) {485Interface I = b.intf("I")486.abstractMethod("m", "()I").build()487.build();488489Interface J = b.intf("J").extend(I)490.defaultMethod("m", "()I")491.private_().returns(1).build()492.build();493494ConcreteClass C = b.clazz("C").implement(J).build();495496b.test().callSite(I, C, "m", "()I").throws_(AbstractMethodError.class).done()497.test().privateCallSite(J, C, "m", "()I").throws_(IllegalAccessError.class).done()498.test().callSite(C, C, "m", "()I").throws_(AbstractMethodError.class).done();499}500501/*502* testPrivateInherited503*504* interface I {505* private int m() { return 1; }506* }507* class B implements I {}508* class C extends B {}509*510* TEST: { I o = new C(); o.m()I throws IllegalAccessError } II I.m511* TEST: { B o = new C(); o.m()I throws NoSuchMethodError }512* TEST: { C o = new C(); o.m()I throws NoSuchMethodError }513*/514public void testPrivateInherited(TestBuilder b) {515Interface I = b.intf("I")516.defaultMethod("m", "()I")517.private_().returns(1).build()518.build();519520ConcreteClass B = b.clazz("B").implement(I).build();521ConcreteClass C = b.clazz("C").extend(B).build();522523b.test().privateCallSite(I, C, "m","()I").throws_(IllegalAccessError.class).done()524.test(). callSite(B, C, "m","()I").throws_(NoSuchMethodError.class).done()525.test(). callSite(C, C, "m","()I").throws_(NoSuchMethodError.class).done();526}527528/*529* testPrivateVsConcreteInherited530*531* interface I {532* private int m() { return 1; }533* }534* class B {535* public int m() { return 2; }536* }537* class C extends B implements I {}538*539* TEST: { I o = new C(); o.m()I == throws IllegalAccessError; }540* TEST: { B o = new C(); o.m()I == 2; }541* TEST: { C o = new C(); o.m()I == 2; }542*/543public void testPrivateVsConcreteInherited(TestBuilder b) {544Interface I = b.intf("I")545.defaultMethod("m", "()I")546.private_().returns(1).build()547.build();548549ConcreteClass B = b.clazz("B")550.concreteMethod("m", "()I").returns(2).build()551.build();552553ConcreteClass C = b.clazz("C").extend(B).implement(I).build();554555b.test().privateCallSite(I, C, "m","()I").throws_(IllegalAccessError.class).done()556.test(). callSite(B, C, "m","()I").returns(2).done()557.test(). callSite(C, C, "m","()I").returns(2).done();558}559560/*561* testPrivateConflict562*563* Conflicting methods564*565* interface I {566* private int m() { return 1; }567* }568* interface J {569* default public int m() { return 2; }570* }571* class C implements I, J {}572*573* TEST: { I o = new C(); o.m()I throws IllegalAccessError; }574* TEST: { J o = new C(); o.m()I == 2; }575* TEST: { C o = new C(); o.m()I == 2; }576*/577public void testPrivateConflict(TestBuilder b) {578Interface I = b.intf("I")579.defaultMethod("m", "()I").private_().returns(1).build()580.build();581582Interface J = b.intf("J")583.defaultMethod("m", "()I").returns(2).build()584.build();585586ConcreteClass C = b.clazz("C").implement(I,J).build();587588b.test().privateCallSite(I, C, "m", "()I").throws_(IllegalAccessError.class).done()589.test(). callSite(J, C, "m", "()I").returns(2).done()590.test(). callSite(C, C, "m", "()I").returns(2).done();591}592/*593* testPrivateSuperClassMethodNoDefaultMethod594*595* interface I {596* public int m();597* }598*599* public class A {600* private int m() { return 1; }601* }602*603* public class B extends A implements I {}604*605* public class C extends B {606* public int m() { return 2; }607* }608*609* TEST: { B b = new C(); b.m()I throws IllegalAccessError; }610*/611public void testPrivateSuperClassMethodNoDefaultMethod(TestBuilder b) {612ConcreteClass A = b.clazz("A")613.concreteMethod("m", "()I").private_().returns(1).build()614.build();615616Interface I = b.intf("I")617.abstractMethod("m", "()I").public_().build()618.build();619620ConcreteClass B = b.clazz("B").extend(A).implement(I).build();621622ConcreteClass C = b.clazz("C").extend(B)623.concreteMethod("m", "()I").public_().returns(2).build()624.build();625626b.test().privateCallSite(B, C, "m", "()I").throws_(IllegalAccessError.class).done();627}628629/*630* testPrivateSuperClassMethodDefaultMethod631*632* interface I {633* public default int m() { return 3; }634* }635*636* public class A {637* private int m() { return 1; }638* }639*640* public class B extends A implements I {}641*642* public class C extends B {643* public int m() { return 2; }644* }645*646* TEST: { B b = new C(); b.m()I throws IllegalAccessError; }647*/648public void testPrivateSuperClassMethodDefaultMethod(TestBuilder b) {649ConcreteClass A = b.clazz("A")650.concreteMethod("m", "()I").private_().returns(1).build()651.build();652653Interface I = b.intf("I")654.defaultMethod("m", "()I").public_().returns(3).build()655.build();656657ConcreteClass B = b.clazz("B").extend(A).implement(I).build();658659ConcreteClass C = b.clazz("C").extend(B)660.concreteMethod("m", "()I").public_().returns(2).build()661.build();662663b.test().privateCallSite(B, C, "m", "()I").throws_(IllegalAccessError.class).done();664}665666/*667* testPrivateSuperClassMethodDefaultMethodNoOverride668*669* interface I {670* public default int m() { return 3; }671* }672*673* public class A {674* private int m() { return 1; }675* }676*677* public class B extends A implements I {}678*679* public class C extends B { }680*681* TEST: { B b = new C(); b.m()I throws IllegalAccessError; }682*/683public void testPrivateSuperClassMethodDefaultMethodNoOverride(TestBuilder b) {684ConcreteClass A = b.clazz("A")685.concreteMethod("m", "()I").private_().returns(1).build()686.build();687688Interface I = b.intf("I")689.defaultMethod("m", "()I").public_().returns(3).build()690.build();691692ConcreteClass B = b.clazz("B").extend(A).implement(I).build();693694ConcreteClass C = b.clazz("C").extend(B).build();695696b.test().privateCallSite(B, C, "m", "()I").throws_(IllegalAccessError.class).done();697}698}699700701