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