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