Path: blob/master/test/functional/Jsr292/src/com/ibm/j9/jsr292/RestrictReceiverTest.java
6007 views
/*******************************************************************************1* Copyright (c) 2014, 2019 IBM Corp. and others2*3* This program and the accompanying materials are made available under4* the terms of the Eclipse Public License 2.0 which accompanies this5* distribution and is available at https://www.eclipse.org/legal/epl-2.0/6* or the Apache License, Version 2.0 which accompanies this distribution and7* is available at https://www.apache.org/licenses/LICENSE-2.0.8*9* This Source Code may also be made available under the following10* Secondary Licenses when the conditions for such availability set11* forth in the Eclipse Public License, v. 2.0 are satisfied: GNU12* General Public License, version 2 with the GNU Classpath13* Exception [1] and GNU General Public License, version 2 with the14* OpenJDK Assembly Exception [2].15*16* [1] https://www.gnu.org/software/classpath/license.html17* [2] http://openjdk.java.net/legal/assembly-exception.html18*19* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception20*******************************************************************************/21package com.ibm.j9.jsr292;2223import org.testng.annotations.Test;24import org.testng.AssertJUnit;25import java.lang.reflect.*;26import java.lang.invoke.*;2728import examples.A;2930public class RestrictReceiverTest {3132private String callMethod(Object testInstance, String method) throws Exception {33Method m = testInstance.getClass().getMethod(method,(Class<?>[] ) null);34return (String) m.invoke(testInstance, (Object[]) null);35}36/**37* This test attempts to perform lookup.unreflect on "protectedMethod" in class A without setting the method38* as accessible.39*40* @param testInstance41*/42@Test(enabled = false)43private void testUnrelfectNoAccess(Object testInstance) {44boolean pass = false;45String result = null;4647try {48result = callMethod(testInstance, "testUnreflectNoAccess");49confirmResult(testInstance, result);50pass = true;51} catch (Exception e) {52if (testInstance instanceof B) {53pass = true;54}55}56AssertJUnit.assertTrue(testInstance.getClass().toString() + "failed testUnreflectNoAccess test", pass);57}585960/**61* This test attempts to perform lookup.unreflect() on a "protectedMethod" in class A and also sets the method62* as accessible.63*64* The spec states:65* "If the method's accessible flag is not set, access checking is performed immediately on behalf of the66* lookup class. If m is not public, do not share the resulting handle with untrusted parties."67* Based on Oracle behaviour "restrictReceiver()" is also not enforced in this case.68*69* @param testInstance70*/71@Test(enabled = false)72private void testUnreflect(Object testInstance) {73boolean pass = false;74String result = null;75pass = false;76try {77result = callMethod(testInstance, "testUnreflect");78pass = true;79} catch (Exception e) {80e.printStackTrace();81}82AssertJUnit.assertTrue(testInstance.getClass().toString() + " was not able to access un-protected member of class A", pass);83confirmResultWithAccess(testInstance, result);84}8586/**87* This test attempts to perform lookup.findVirtual() on a "protectedMethod" in class A.88*89* @param testInstance90*/91@Test(enabled = false)92private void testFindVirtual(Object testInstance) {93boolean pass = false;94String result = null;95try {96result = callMethod(testInstance, "testFindVirtual");97confirmResult(testInstance, result);98pass = true;99} catch (Exception e) {100if (testInstance instanceof B) {101pass = true;102//class B is not a subclass of A103} else {104e.printStackTrace();105}106}107AssertJUnit.assertTrue(testInstance.getClass().toString() + "did not properly access member of class A via findVirtual", pass);108}109110/**111* This test attempts to perform lookup.findSpecial() on a "protectedMethod" in class A. This112* test uses the instanceClass as the specialToken113*114* @param testInstance115*/116@Test(enabled = false)117private void testFindSpecialSameTokenAsCurrentClass(Object testInstance) {118boolean pass = false;119String result = null;120try {121result = callMethod(testInstance, "testFindSpecialSameTokenAsClass");122confirmResultSpecial(testInstance, result);123pass = true;124} catch (Exception e) {125if (testInstance instanceof B) {126pass = true;127//class B is not a subclass of A128} else {129e.printStackTrace();130}131}132AssertJUnit.assertTrue(testInstance.getClass().toString() + "did not properly access member of class A via findSpecial", pass);133}134135/**136* This test attempts to perform lookup.findSpecial() on a "protectedMethod" in class A. This137* test use class A as the specialToken138*139* @param testInstance140*/141@Test(enabled = false)142private void testFindSpecial(Object testInstance) {143boolean pass = false;144String result = null;145try {146result = callMethod(testInstance, "testFindSpecial");147result = callMethod(testInstance, "testFindSpecial");//twice so we can get the cached value148confirmResultSpecial(testInstance, result);149} catch (Exception e) {150pass = true;// none of the classes have private access for invokespecial in class apackage.A151}152AssertJUnit.assertTrue(testInstance.getClass().toString() + "did not properly access member of class A via findSpecial", pass);153}154155/**156* This test attempts to perform lookup.bind() on a "protectedMethod" in class A.157*158* @param testInstance159*/160@Test(enabled = false)161private void testBind(Object testInstance) {162boolean pass = false;163String result = null;164try {165result = callMethod(testInstance, "testBind");166confirmResultBind(testInstance, result);167pass = true;168} catch (Exception e) {169if (testInstance instanceof B) {170pass = true;//B has no access171} else {172e.printStackTrace();173}174}175AssertJUnit.assertTrue(testInstance.getClass().toString() + "did not properly access member of class A via bind", pass);176}177178/**179* Runs all the test methods180*181* @param testInstance182*/183184@Test(enabled = false)185private void testClass(Object testInstance) {186testUnrelfectNoAccess(testInstance);187testUnreflect(testInstance);188testFindVirtual(testInstance);189testFindSpecialSameTokenAsCurrentClass(testInstance);190testFindSpecial(testInstance);191testBind(testInstance);192}193194private void confirmResult(Object testClass, String result) {195if (testClass instanceof B) {196AssertJUnit.assertTrue("class B has no access", false);197} else if (testClass instanceof D) {198AssertJUnit.assertEquals("class D return the wrong methodType", "(Lcom/ibm/j9/jsr292/C;)V", result);199} else if (testClass instanceof C) {200AssertJUnit.assertEquals("class C return the wrong methodType", "(Lcom/ibm/j9/jsr292/C;)V", result);201}202}203204private void confirmResultSpecial(Object testClass, String result) {205if (testClass instanceof B) {206AssertJUnit.assertTrue("class B has no findSpecial access", false);207} else if (testClass instanceof D) {208AssertJUnit.assertEquals("class D return the wrong methodType", "(Lcom/ibm/j9/jsr292/D;)V", result);209} else if (testClass instanceof C) {210AssertJUnit.assertEquals("class C return the wrong methodType", "(Lcom/ibm/j9/jsr292/C;)V", result);211}212}213214private void confirmResultBind(Object testClass, String result) {215if (testClass instanceof B) {216AssertJUnit.assertTrue("class B has no Bind access", false);217} else if (testClass instanceof D) {218AssertJUnit.assertEquals("class D return the wrong methodType", "()V", result);219} else if (testClass instanceof C) {220AssertJUnit.assertEquals("class C return the wrong methodType", "()V", result);221}222}223224private void confirmResultWithAccess(Object testClass, String result) {225AssertJUnit.assertEquals(testClass.getClass().toString() + " returned the wrong methodType", "(Lexamples/A;)V", result);226}227228/**229* Main test case, runs test methods on class B, C, and D230*231*/232@Test(groups = { "level.extended" })233public void testRestrictReceiver() {234testClass(new B());235testClass(new C());236testClass(new D());237}238}239240class B {241public String testUnreflectNoAccess() throws Exception {242Method m = A.getMethod("protectedMethod");243MethodHandle mh = MethodHandles.lookup().unreflect(m);244return mh.type().toMethodDescriptorString();245}246247public String testUnreflect() throws Exception {248Method m = A.getMethod("protectedMethod");249m.setAccessible(true);250MethodHandle mh = MethodHandles.lookup().unreflect(m);251return mh.type().toMethodDescriptorString();252}253254public String testFindVirtual() throws Exception {255MethodHandle mh = MethodHandles.lookup().findVirtual(A.class, "protectedMethod", MethodType.methodType(void.class));256return mh.type().toMethodDescriptorString();257}258259public String testFindSpecialSameTokenAsClass() throws Exception {260MethodHandle mh = MethodHandles.lookup().findSpecial(A.class, "protectedMethod", MethodType.methodType(void.class), B.class);261return mh.type().toMethodDescriptorString();262}263264public String testFindSpecial() throws Exception {265MethodHandle mh = MethodHandles.lookup().findSpecial(A.class, "protectedMethod", MethodType.methodType(void.class), A.class);266return mh.type().toMethodDescriptorString();267}268269public String testBind() throws Exception {270MethodHandle mh = MethodHandles.lookup().bind(new B(), "protectedMethod", MethodType.methodType(void.class));271return mh.type().toMethodDescriptorString();272}273}274275class C extends A {276public String testUnreflectNoAccess() throws Exception {277Method m = A.getMethod("protectedMethod");278MethodHandle mh = MethodHandles.lookup().unreflect(m);279return mh.type().toMethodDescriptorString();280}281282public String testUnreflect() throws Exception {283Method m = A.getMethod("protectedMethod");284m.setAccessible(true);285MethodHandle mh = MethodHandles.lookup().unreflect(m);286return mh.type().toMethodDescriptorString();287}288289public String testFindVirtual() throws Exception {290MethodHandle mh = MethodHandles.lookup().findVirtual(A.class, "protectedMethod", MethodType.methodType(void.class));291return mh.type().toMethodDescriptorString();292}293294public String testFindSpecialSameTokenAsClass() throws Exception {295MethodHandle mh = MethodHandles.lookup().findSpecial(A.class, "protectedMethod", MethodType.methodType(void.class), C.class);296return mh.type().toMethodDescriptorString();297}298299public String testFindSpecial() throws Exception {300MethodHandle mh = MethodHandles.lookup().findSpecial(A.class, "protectedMethod", MethodType.methodType(void.class), A.class);301return mh.type().toMethodDescriptorString();302}303304public String testBind() throws Exception {305MethodHandle mh = MethodHandles.lookup().bind(new C(), "protectedMethod", MethodType.methodType(void.class));306return mh.type().toMethodDescriptorString();307}308}309310class D extends C {311@Override312public String testFindSpecialSameTokenAsClass() throws Exception {313MethodHandle mh = MethodHandles.lookup().findSpecial(A.class, "protectedMethod", MethodType.methodType(void.class), D.class);314return mh.type().toMethodDescriptorString();315}316317@Override318public String testFindSpecial() throws Exception {319MethodHandle mh = MethodHandles.lookup().findSpecial(A.class, "protectedMethod", MethodType.methodType(void.class), A.class);320return mh.type().toMethodDescriptorString();321}322323@Override324public String testBind() throws Exception {325MethodHandle mh = MethodHandles.lookup().bind(new D(), "protectedMethod", MethodType.methodType(void.class));326return mh.type().toMethodDescriptorString();327}328}329330331