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 and nest-top 28 * using different flavours of named nested types using MethodHandles 29 * @run main TestMethodHandles 30 */ 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 TestMethodHandles { 38 39 static final MethodType M_T = MethodType.methodType(void.class); 40 41 // Private method of nest-top for nestmates to access 42 private void priv_invoke() { 43 System.out.println("TestMethodHandles::priv_invoke"); 44 } 45 46 // public constructor so we aren't relying on private access 47 public TestMethodHandles() {} 48 49 // Methods that will access private methods of nestmates 50 51 void access_priv(TestMethodHandles o) throws Throwable { 52 MethodHandle mh = 53 lookup().findSpecial(o.getClass(), "priv_invoke", M_T, this.getClass()); 54 mh.invoke(o); 55 mh.invokeExact(o); 56 checkBadInvoke(mh, new StaticNested()); // wrong nestmate 57 checkBadInvoke(mh, mh); // completely wrong type 58 } 59 void access_priv(InnerNested o) throws Throwable { 60 MethodHandle mh = 61 lookup().findSpecial(o.getClass(), "priv_invoke", M_T, this.getClass()); 62 mh.invoke(o); 63 mh.invokeExact(o); 64 checkBadInvoke(mh, this); // wrong nestmate 65 checkBadInvoke(mh, mh); // completely wrong type 66 } 67 void access_priv(StaticNested o) throws Throwable { 68 MethodHandle mh = 69 lookup().findSpecial(o.getClass(), "priv_invoke", M_T, this.getClass()); 70 mh.invoke(o); 71 mh.invokeExact(o); 72 checkBadInvoke(mh, this); // wrong nestmate 73 checkBadInvoke(mh, mh); // completely wrong type 74 } 75 void access_priv(StaticIface o) throws Throwable { 76 MethodHandle mh = 77 lookup().findSpecial(StaticIface.class, "priv_invoke", M_T, this.getClass()); 78 mh.invoke(o); 79 mh.invokeExact(o); 80 checkBadInvoke(mh, this); // wrong nestmate 81 checkBadInvoke(mh, mh); // completely wrong type 82 } 83 84 // The various nestmates 85 86 static interface StaticIface { 87 88 private void priv_invoke() { 89 System.out.println("StaticIface::priv_invoke"); 90 } 91 92 // Methods that will access private methods of nestmates 93 94 default void access_priv(TestMethodHandles o) throws Throwable { 95 MethodHandle mh = 96 lookup().findSpecial(o.getClass(), "priv_invoke", M_T, StaticIface.class); 97 mh.invoke(o); 98 mh.invokeExact(o); 99 checkBadInvoke(mh, this); // wrong nestmate 100 checkBadInvoke(mh, mh); // completely wrong type 101 } 102 default void access_priv(InnerNested o) throws Throwable { 103 MethodHandle mh = 104 lookup().findSpecial(o.getClass(), "priv_invoke", M_T, StaticIface.class); 105 mh.invoke(o); 106 mh.invokeExact(o); 107 checkBadInvoke(mh, this); // wrong nestmate 108 checkBadInvoke(mh, mh); // completely wrong type 109 } 110 default void access_priv(StaticNested o) throws Throwable { 111 MethodHandle mh = 112 lookup().findSpecial(o.getClass(), "priv_invoke", M_T, StaticIface.class); 113 mh.invoke(o); 114 mh.invokeExact(o); 115 checkBadInvoke(mh, this); // wrong nestmate 116 checkBadInvoke(mh, mh); // completely wrong type 117 } 118 default void access_priv(StaticIface o) throws Throwable { 119 MethodHandle mh = 120 lookup().findSpecial(StaticIface.class, "priv_invoke", M_T, StaticIface.class); 121 mh.invoke(o); 122 mh.invokeExact(o); 123 checkBadInvoke(mh, new StaticNested()); // wrong nestmate 124 checkBadInvoke(mh, mh); // completely wrong type 125 } 126 } 127 128 static class StaticNested { 129 130 private void priv_invoke() { 131 System.out.println("StaticNested::priv_invoke"); 132 } 133 134 // public constructor so we aren't relying on private access 135 public StaticNested() {} 136 137 // Methods that will access private methods of nestmates 138 139 void access_priv(TestMethodHandles o) throws Throwable { 140 MethodHandle mh = 141 lookup().findSpecial(o.getClass(), "priv_invoke", M_T, this.getClass()); 142 mh.invoke(o); 143 mh.invokeExact(o); 144 checkBadInvoke(mh, this); // wrong nestmate 145 checkBadInvoke(mh, mh); // completely wrong type 146 } 147 void access_priv(InnerNested o) throws Throwable { 148 MethodHandle mh = 149 lookup().findSpecial(o.getClass(), "priv_invoke", M_T, this.getClass()); 150 mh.invoke(o); 151 mh.invokeExact(o); 152 checkBadInvoke(mh, this); // wrong nestmate 153 checkBadInvoke(mh, mh); // completely wrong type 154 } 155 void access_priv(StaticNested o) throws Throwable { 156 MethodHandle mh = 157 lookup().findSpecial(o.getClass(), "priv_invoke", M_T, this.getClass()); 158 mh.invoke(o); 159 mh.invokeExact(o); 160 checkBadInvoke(mh, new TestMethodHandles()); // wrong nestmate 161 checkBadInvoke(mh, mh); // completely wrong type 162 } 163 void access_priv(StaticIface o) throws Throwable { 164 MethodHandle mh = 165 lookup().findSpecial(StaticIface.class, "priv_invoke", M_T, this.getClass()); 166 mh.invoke(o); 167 mh.invokeExact(o); 168 checkBadInvoke(mh, this); // wrong nestmate 169 checkBadInvoke(mh, mh); // completely wrong type 170 } 171 } 172 173 class InnerNested { 174 175 private void priv_invoke() { 176 System.out.println("InnerNested::priv_invoke"); 177 } 178 179 // public constructor so we aren't relying on private access 180 public InnerNested() {} 181 182 void access_priv(TestMethodHandles o) throws Throwable { 183 MethodHandle mh = 184 lookup().findSpecial(o.getClass(), "priv_invoke", M_T, this.getClass()); 185 mh.invoke(o); 186 mh.invokeExact(o); 187 checkBadInvoke(mh, this); // wrong nestmate 188 checkBadInvoke(mh, mh); // completely wrong type 189 } 190 void access_priv(InnerNested o) throws Throwable { 191 MethodHandle mh = 192 lookup().findSpecial(o.getClass(), "priv_invoke", M_T, this.getClass()); 193 mh.invoke(o); 194 mh.invokeExact(o); 195 checkBadInvoke(mh, new StaticNested()); // wrong nestmate 196 checkBadInvoke(mh, mh); // completely wrong type 197 } 198 void access_priv(StaticNested o) throws Throwable { 199 MethodHandle mh = 200 lookup().findSpecial(o.getClass(), "priv_invoke", M_T, this.getClass()); 201 mh.invoke(o); 202 mh.invokeExact(o); 203 checkBadInvoke(mh, this); // wrong nestmate 204 checkBadInvoke(mh, mh); // completely wrong type 205 } 206 void access_priv(StaticIface o) throws Throwable { 207 MethodHandle mh = 208 lookup().findSpecial(StaticIface.class, "priv_invoke", M_T, this.getClass()); 209 mh.invoke(o); 210 mh.invokeExact(o); 211 checkBadInvoke(mh, this); // wrong nestmate 212 checkBadInvoke(mh, mh); // completely wrong type 213 } 214 } 215 216 static void checkBadInvoke(MethodHandle mh, Object o) throws Throwable { 217 try { 218 mh.invoke(o); 219 throw new Error("Invoke on MethodHandle " + mh + " with receiver " 220 + o + "should have failed with ClassCastException!"); 221 } 222 catch (ClassCastException expected) { 223 System.out.println("invoke got expected exception: " + expected); 224 } 225 } 226 227 public static void main(String[] args) throws Throwable { 228 TestMethodHandles o = new TestMethodHandles(); 229 StaticNested s = new StaticNested(); 230 InnerNested i = o.new InnerNested(); 231 StaticIface intf = new StaticIface() {}; 232 233 o.access_priv(new TestMethodHandles()); 234 o.access_priv(i); 235 o.access_priv(s); 236 o.access_priv(intf); 237 238 s.access_priv(o); 239 s.access_priv(i); 240 s.access_priv(new StaticNested()); 241 s.access_priv(intf); 242 243 i.access_priv(o); 244 i.access_priv(o.new InnerNested()); 245 i.access_priv(s); 246 i.access_priv(intf); 247 248 intf.access_priv(o); 249 intf.access_priv(i); 250 intf.access_priv(s); 251 intf.access_priv(new StaticIface(){}); 252 } 253 }