test/hotspot/jtreg/runtime/Nestmates/privateMethods/TestMethodHandlesHierarchy.java
changeset 50735 2f2af62dfac7
equal deleted inserted replaced
50734:0828a0f6676b 50735:2f2af62dfac7
       
     1 /*
       
     2  * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
       
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       
     4  *
       
     5  * This code is free software; you can redistribute it and/or modify it
       
     6  * under the terms of the GNU General Public License version 2 only, as
       
     7  * published by the Free Software Foundation.
       
     8  *
       
     9  * This code is distributed in the hope that it will be useful, but WITHOUT
       
    10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    12  * version 2 for more details (a copy is included in the LICENSE file that
       
    13  * accompanied this code).
       
    14  *
       
    15  * You should have received a copy of the GNU General Public License version
       
    16  * 2 along with this work; if not, write to the Free Software Foundation,
       
    17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       
    18  *
       
    19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
       
    20  * or visit www.oracle.com if you need additional information or have any
       
    21  * questions.
       
    22  */
       
    23 
       
    24 /*
       
    25  * @test
       
    26  * @bug 8046171
       
    27  * @summary Test access to private methods between nestmates where there
       
    28  *          is an inheritance hierarchy and we invoke private methods that
       
    29  *          exist in specific classes in the hierarchy.
       
    30  * @run main TestMethodHandlesHierarchy
       
    31  */
       
    32 
       
    33 import java.lang.invoke.*;
       
    34 import static java.lang.invoke.MethodHandles.*;
       
    35 import static java.lang.invoke.MethodType.*;
       
    36 
       
    37 public class TestMethodHandlesHierarchy {
       
    38 
       
    39    static final MethodType M_T = MethodType.methodType(String.class);
       
    40 
       
    41     static class NestedA extends ExternalSuper {
       
    42         static final String ID =  "NestedA::priv_invoke";
       
    43         private String priv_invoke() {
       
    44             return ID;
       
    45         }
       
    46         static void checkA(NestedA a) throws Throwable {
       
    47             MethodHandle mh =
       
    48                 lookup().findSpecial(NestedA.class, "priv_invoke",
       
    49                                      M_T,  NestedA.class);
       
    50             verifyEquals((String)mh.invoke(a), NestedA.ID);
       
    51             verifyEquals((String)mh.invokeExact(a), NestedA.ID);
       
    52 
       
    53             mh = lookup().findVirtual(NestedA.class, "priv_invoke", M_T);
       
    54             verifyEquals((String)mh.invoke(a), NestedA.ID);
       
    55             verifyEquals((String)mh.invokeExact(a), NestedA.ID);
       
    56         }
       
    57     }
       
    58 
       
    59     static class NestedB extends NestedA {
       
    60         static final String ID =  "NestedB::priv_invoke";
       
    61         private String priv_invoke() {
       
    62             return ID;
       
    63         }
       
    64         static void checkA(NestedA a) throws Throwable {
       
    65             MethodHandle mh =
       
    66                 lookup().findVirtual(NestedA.class, "priv_invoke", M_T);
       
    67             verifyEquals((String)mh.invoke(a), NestedA.ID);
       
    68             verifyEquals((String)mh.invokeExact(a), NestedA.ID);
       
    69         }
       
    70     }
       
    71 
       
    72     static class NestedC extends NestedB {
       
    73         static final String ID =  "NestedC::priv_invoke";
       
    74         private String priv_invoke() {
       
    75             return ID;
       
    76         }
       
    77         static void checkA(NestedA a) throws Throwable {
       
    78             MethodHandle mh =
       
    79                 lookup().findVirtual(NestedA.class, "priv_invoke", M_T);
       
    80             verifyEquals((String)mh.invoke(a), NestedA.ID);
       
    81             verifyEquals((String)mh.invokeExact(a), NestedA.ID);
       
    82         }
       
    83     }
       
    84 
       
    85     static void checkA(NestedA a) throws Throwable {
       
    86             MethodHandle mh =
       
    87                 lookup().findVirtual(NestedA.class, "priv_invoke", M_T);
       
    88             verifyEquals((String)mh.invoke(a), NestedA.ID);
       
    89             verifyEquals((String)mh.invokeExact(a), NestedA.ID);
       
    90     }
       
    91 
       
    92     static void checkB(NestedB b) throws Throwable {
       
    93             MethodHandle mh =
       
    94                 lookup().findVirtual(NestedB.class, "priv_invoke", M_T);
       
    95             verifyEquals((String)mh.invoke(b), NestedB.ID);
       
    96             verifyEquals((String)mh.invokeExact(b), NestedB.ID);
       
    97     }
       
    98 
       
    99     static void checkC(NestedC c) throws Throwable {
       
   100             MethodHandle mh =
       
   101                 lookup().findVirtual(NestedC.class, "priv_invoke", M_T);
       
   102             verifyEquals((String)mh.invoke(c), NestedC.ID);
       
   103             verifyEquals((String)mh.invokeExact(c), NestedC.ID);
       
   104     }
       
   105 
       
   106 
       
   107     // Access to private members of classes outside the nest is
       
   108     // not permitted. These tests should throw IllegalAccessException
       
   109     // at runtime.
       
   110 
       
   111     static void checkExternalSuper(ExternalSuper s) throws Throwable {
       
   112         try {
       
   113             lookup().findVirtual(ExternalSuper.class, "priv_invoke", M_T);
       
   114             throw new Error("Unexpected access to ExternalSuper.priv_invoke");
       
   115         }
       
   116         catch (IllegalAccessException iae) {
       
   117             System.out.println("Got expected exception accessing ExternalSuper.priv_invoke:" + iae);
       
   118         }
       
   119     }
       
   120 
       
   121     static void checkExternalSub(ExternalSub s) throws Throwable {
       
   122         try {
       
   123             lookup().findVirtual(ExternalSub.class, "priv_invoke", M_T);
       
   124             throw new Error("Unexpected access to ExternalSub.priv_invoke");
       
   125         }
       
   126         catch (IllegalAccessException iae) {
       
   127             System.out.println("Got expected exception accessing ExternalSub.priv_invoke:" + iae);
       
   128         }
       
   129     }
       
   130 
       
   131     static void verifyEquals(String actual, String expected) {
       
   132         if (!actual.equals(expected)) {
       
   133             throw new Error("Expected " + expected + " but got " + actual);
       
   134         }
       
   135         System.out.println("Check passed for " + expected);
       
   136     }
       
   137 
       
   138     public static void main(String[] args) throws Throwable {
       
   139         NestedA a = new NestedA();
       
   140         NestedB b = new NestedB();
       
   141         NestedC c = new NestedC();
       
   142         ExternalSub sub = new ExternalSub();
       
   143         ExternalSuper sup = new ExternalSuper();
       
   144 
       
   145         checkExternalSuper(sup);
       
   146         checkExternalSuper(a);
       
   147         checkExternalSuper(b);
       
   148         checkExternalSuper(c);
       
   149         checkExternalSuper(sub);
       
   150 
       
   151         checkA(a);
       
   152         checkA(b);
       
   153         checkA(c);
       
   154         checkA(sub);
       
   155 
       
   156         NestedA.checkA(a);
       
   157         NestedA.checkA(b);
       
   158         NestedA.checkA(c);
       
   159         NestedA.checkA(sub);
       
   160 
       
   161         NestedB.checkA(a);
       
   162         NestedB.checkA(b);
       
   163         NestedB.checkA(c);
       
   164         NestedB.checkA(sub);
       
   165 
       
   166         NestedC.checkA(a);
       
   167         NestedC.checkA(b);
       
   168         NestedC.checkA(c);
       
   169         NestedC.checkA(sub);
       
   170 
       
   171         checkB(b);
       
   172         checkB(c);
       
   173         checkB(sub);
       
   174 
       
   175         checkC(c);
       
   176         checkC(sub);
       
   177 
       
   178         checkExternalSub(sub);
       
   179     }
       
   180 }
       
   181 
       
   182 // Classes that are not part of the nest.
       
   183 // Being non-public allows us to declare them in this file.
       
   184 
       
   185 class ExternalSuper {
       
   186     static final String ID =  "ExternalSuper::priv_invoke";
       
   187     private String priv_invoke() {
       
   188         return ID;
       
   189     }
       
   190 }
       
   191 
       
   192 
       
   193 class ExternalSub extends TestMethodHandlesHierarchy.NestedC {
       
   194     static final String ID =  "ExternalSub::priv_invoke";
       
   195     private String priv_invoke() {
       
   196         return ID;
       
   197     }
       
   198 }