test/compiler/jsr292/methodHandleExceptions/TestAMEnotNPE.java

Wed, 21 Jan 2015 12:38:11 +0100

author
goetz
date
Wed, 21 Jan 2015 12:38:11 +0100
changeset 7574
a51071796915
parent 6134
9d15b81d5d1b
child 6876
710a3c8b516e
permissions
-rw-r--r--

8068013: [TESTBUG] Aix support in hotspot jtreg tests
Reviewed-by: ctornqvi, fzhinkin, farvidsson

drchase@5800 1 /*
drchase@5800 2 * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
drchase@5800 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
drchase@5800 4 *
drchase@5800 5 * This code is free software; you can redistribute it and/or modify it
drchase@5800 6 * under the terms of the GNU General Public License version 2 only, as
drchase@5800 7 * published by the Free Software Foundation.
drchase@5800 8 *
drchase@5800 9 * This code is distributed in the hope that it will be useful, but WITHOUT
drchase@5800 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
drchase@5800 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
drchase@5800 12 * version 2 for more details (a copy is included in the LICENSE file that
drchase@5800 13 * accompanied this code).
drchase@5800 14 *
drchase@5800 15 * You should have received a copy of the GNU General Public License version
drchase@5800 16 * 2 along with this work; if not, write to the Free Software Foundation,
drchase@5800 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
drchase@5800 18 *
drchase@5800 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
drchase@5800 20 * or visit www.oracle.com if you need additional information or have any
drchase@5800 21 * questions.
drchase@5800 22 *
drchase@5800 23 */
drchase@5800 24 import java.lang.reflect.InvocationTargetException;
drchase@6134 25 import java.lang.reflect.Method;
drchase@6134 26 import java.util.ArrayList;
drchase@6134 27 import java.util.List;
drchase@5800 28 import jdk.internal.org.objectweb.asm.ClassWriter;
drchase@5800 29 import jdk.internal.org.objectweb.asm.Handle;
drchase@5800 30 import jdk.internal.org.objectweb.asm.MethodVisitor;
drchase@5800 31 import jdk.internal.org.objectweb.asm.Opcodes;
drchase@6134 32 import p.Dok;
drchase@5800 33
drchase@5800 34 /**
drchase@6134 35 * @test @bug 8025260 8016839
drchase@6134 36 * @summary Ensure that AbstractMethodError and IllegalAccessError are thrown appropriately, not NullPointerException
drchase@5800 37 *
drchase@6134 38 * @compile -XDignore.symbol.file TestAMEnotNPE.java ByteClassLoader.java p/C.java p/Dok.java p/E.java p/F.java p/I.java p/Tdirect.java p/Treflect.java
drchase@6134 39 *
drchase@5800 40 * @run main/othervm TestAMEnotNPE
drchase@6134 41 * @run main/othervm -Xint TestAMEnotNPE
drchase@6134 42 * @run main/othervm -Xcomp TestAMEnotNPE
drchase@5800 43 */
drchase@5800 44 public class TestAMEnotNPE implements Opcodes {
drchase@5800 45
drchase@6134 46 static boolean writeJarFiles = false;
drchase@6134 47 static boolean readJarFiles = false;
drchase@6134 48
drchase@5800 49 /**
drchase@6134 50 * Optional command line parameter (any case-insensitive prefix of)
drchase@6134 51 * "writejarfiles" or "readjarfiles".
drchase@6134 52 *
drchase@6134 53 * "Writejarfiles" creates a jar file for each different set of tested classes.
drchase@6134 54 * "Readjarfiles" causes the classloader to use the copies of the classes
drchase@6134 55 * found in the corresponding jar files.
drchase@6134 56 *
drchase@6134 57 * Jarfilenames look something like pD_ext_pF (p.D extends p.F)
drchase@6134 58 * and qD_m_pp_imp_pI (q.D with package-private m implements p.I)
drchase@6134 59 *
drchase@6134 60 */
drchase@6134 61 public static void main(String args[]) throws Throwable {
drchase@6134 62 ArrayList<Throwable> lt = new ArrayList<Throwable>();
drchase@5800 63
drchase@6134 64 if (args.length > 0) {
drchase@6134 65 String a0 = args[0].toLowerCase();
drchase@6134 66 if (a0.length() > 0) {
drchase@6134 67 writeJarFiles = ("writejarfiles").startsWith(a0);
drchase@6134 68 readJarFiles = ("readjarfiles").startsWith(a0);
drchase@6134 69 }
drchase@6134 70 if (!(writeJarFiles || readJarFiles)) {
drchase@6134 71 throw new Error("Command line parameter (if any) should be prefix of writeJarFiles or readJarFiles");
drchase@6134 72 }
drchase@6134 73 }
drchase@5800 74
drchase@6134 75 try {
drchase@6134 76 System.out.println("TRYING p.D.m PRIVATE interface-invoked as p.I.m, p.D extends p.F, p.F.m FINAL");
drchase@6134 77 tryAndCheckThrown(lt, bytesForDprivateSubWhat("p/F"),
drchase@6134 78 "p.D extends p.F (p.F implements p.I, FINAL public m), private m",
drchase@6134 79 IllegalAccessError.class, "pD_ext_pF");
drchase@6134 80 // We'll take either a VerifyError (pre 2013-11-30)
drchase@6134 81 // or an IllegalAccessError (post 2013-11-22)
drchase@6134 82 } catch (VerifyError ve) {
drchase@6134 83 System.out.println("Saw expected VerifyError " + ve);
drchase@6134 84 }
drchase@6134 85 System.out.println();
drchase@6134 86
drchase@6134 87 System.out.println("TRYING p.D.m PRIVATE interface-invoked as p.I.m, p.D extends p.E");
drchase@6134 88 tryAndCheckThrown(lt, bytesForDprivateSubWhat("p/E"),
drchase@6134 89 "p.D extends p.E (p.E implements p.I, public m), private m",
drchase@6134 90 IllegalAccessError.class, "pD_ext_pE");
drchase@6134 91
drchase@6134 92 System.out.println("TRYING p.D.m ABSTRACT interface-invoked as p.I.m");
drchase@6134 93 tryAndCheckThrown(lt, bytesForD(),
drchase@6134 94 "D extends abstract C, no m",
drchase@6134 95 AbstractMethodError.class, "pD_ext_pC");
drchase@6134 96
drchase@6134 97 System.out.println("TRYING q.D.m PACKAGE interface-invoked as p.I.m");
drchase@6134 98 tryAndCheckThrown(lt, "q.D", bytesForDsomeAccess("q/D", 0),
drchase@6134 99 "q.D implements p.I, protected m", IllegalAccessError.class,
drchase@6134 100 "qD_m_pp_imp_pI");
drchase@6134 101
drchase@6134 102 // Note jar file name is used in the plural-arg case.
drchase@6134 103 System.out.println("TRYING p.D.m PRIVATE interface-invoked as p.I.m");
drchase@6134 104 tryAndCheckThrown(lt, bytesForDsomeAccess("p/D", ACC_PRIVATE),
drchase@6134 105 "p.D implements p.I, private m",
drchase@6134 106 IllegalAccessError.class, "pD_m_pri_imp_pI");
drchase@6134 107
drchase@6134 108 // Plural-arg test.
drchase@6134 109 System.out.println("TRYING p.D.m PRIVATE MANY ARG interface-invoked as p.I.m");
drchase@6134 110 tryAndCheckThrownMany(lt, bytesForDsomeAccess("p/D", ACC_PRIVATE),
drchase@6134 111 "p.D implements p.I, private m", IllegalAccessError.class);
drchase@6134 112
drchase@6134 113 if (lt.size() > 0) {
drchase@6134 114 System.out.flush();
drchase@6134 115 Thread.sleep(250); // This de-interleaves output and error in Netbeans, sigh.
drchase@6134 116 for (Throwable th : lt)
drchase@6134 117 System.err.println(th);
drchase@6134 118 throw new Error("Test failed, there were " + lt.size() + " failures listed above");
drchase@6134 119 } else {
drchase@6134 120 System.out.println("ALL PASS, HOORAY!");
drchase@6134 121 }
drchase@6134 122 }
drchase@6134 123
drchase@6134 124 /**
drchase@6134 125 * The bytes for D, a NOT abstract class extending abstract class C without
drchase@6134 126 * supplying an implementation for abstract method m. There is a default
drchase@6134 127 * method in the interface I, but it should lose to the abstract class.
drchase@6134 128 *
drchase@5800 129 * @return
drchase@5800 130 * @throws Exception
drchase@5800 131 */
drchase@5800 132 public static byte[] bytesForD() throws Exception {
drchase@5800 133
drchase@6134 134 ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES
drchase@6134 135 | ClassWriter.COMPUTE_MAXS);
drchase@5800 136 MethodVisitor mv;
drchase@5800 137
drchase@6134 138 cw.visit(V1_8, ACC_PUBLIC + ACC_SUPER, "p/D", null, "p/C", null);
drchase@5800 139
drchase@5800 140 {
drchase@5800 141 mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
drchase@5800 142 mv.visitCode();
drchase@5800 143 mv.visitVarInsn(ALOAD, 0);
drchase@6134 144 mv.visitMethodInsn(INVOKESPECIAL, "p/C", "<init>", "()V");
drchase@5800 145 mv.visitInsn(RETURN);
drchase@5800 146 mv.visitMaxs(0, 0);
drchase@5800 147 mv.visitEnd();
drchase@5800 148 }
drchase@5800 149 cw.visitEnd();
drchase@5800 150
drchase@5800 151 return cw.toByteArray();
drchase@5800 152 }
drchase@5800 153
drchase@6134 154 /**
drchase@6134 155 * The bytes for D, implements I, does not extend C, declares m()I with
drchase@6134 156 * access method_acc.
drchase@6134 157 *
drchase@6134 158 * @param d_name Name of class defined
drchase@6134 159 * @param method_acc Accessibility of that class's method m.
drchase@6134 160 * @return
drchase@6134 161 * @throws Exception
drchase@6134 162 */
drchase@6134 163 public static byte[] bytesForDsomeAccess(String d_name, int method_acc) throws Exception {
drchase@6134 164 return bytesForSomeDsubSomethingSomeAccess(d_name, "java/lang/Object", method_acc);
drchase@6134 165 }
drchase@5800 166
drchase@5800 167 /**
drchase@6134 168 * The bytes for D implements I, extends some class, declares m()I as
drchase@6134 169 * private.
drchase@6134 170 *
drchase@6134 171 * Invokeinterface of I.m applied to this D should throw IllegalAccessError
drchase@6134 172 *
drchase@6134 173 * @param sub_what The name of the class that D will extend.
drchase@6134 174 * @return
drchase@6134 175 * @throws Exception
drchase@6134 176 */
drchase@6134 177 public static byte[] bytesForDprivateSubWhat(String sub_what) throws Exception {
drchase@6134 178 return bytesForSomeDsubSomethingSomeAccess("p/D", sub_what, ACC_PRIVATE);
drchase@6134 179 }
drchase@5800 180
drchase@6134 181 /**
drchase@6134 182 * Returns the bytes for a class with name d_name (presumably "D" in some
drchase@6134 183 * package), extending some class with name sub_what, implementing p.I,
drchase@6134 184 * and defining two methods m() and m(11args) with access method_acc.
drchase@6134 185 *
drchase@6134 186 * @param d_name Name of class that is defined
drchase@6134 187 * @param sub_what Name of class that it extends
drchase@6134 188 * @param method_acc Accessibility of method(s) m in defined class.
drchase@6134 189 * @return
drchase@6134 190 * @throws Exception
drchase@6134 191 */
drchase@6134 192 public static byte[] bytesForSomeDsubSomethingSomeAccess
drchase@6134 193 (String d_name, String sub_what, int method_acc)
drchase@6134 194 throws Exception {
drchase@6134 195
drchase@6134 196 ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES
drchase@6134 197 | ClassWriter.COMPUTE_MAXS);
drchase@6134 198 MethodVisitor mv;
drchase@6134 199 String[] interfaces = {"p/I"};
drchase@6134 200
drchase@6134 201 cw.visit(V1_8, ACC_PUBLIC + ACC_SUPER, d_name, null, sub_what, interfaces);
drchase@6134 202 {
drchase@6134 203 mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
drchase@6134 204 mv.visitCode();
drchase@6134 205 mv.visitVarInsn(ALOAD, 0);
drchase@6134 206 mv.visitMethodInsn(INVOKESPECIAL, sub_what, "<init>", "()V");
drchase@6134 207 mv.visitInsn(RETURN);
drchase@6134 208 mv.visitMaxs(0, 0);
drchase@6134 209 mv.visitEnd();
drchase@5800 210 }
drchase@6134 211 // int m() {return 3;}
drchase@6134 212 {
drchase@6134 213 mv = cw.visitMethod(method_acc, "m", "()I", null, null);
drchase@6134 214 mv.visitCode();
drchase@6134 215 mv.visitLdcInsn(new Integer(3));
drchase@6134 216 mv.visitInsn(IRETURN);
drchase@6134 217 mv.visitMaxs(0, 0);
drchase@6134 218 mv.visitEnd();
drchase@6134 219 }
drchase@6134 220 // int m(11args) {return 3;}
drchase@6134 221 {
drchase@6134 222 mv = cw.visitMethod(method_acc, "m", "(BCSIJ"
drchase@6134 223 + "Ljava/lang/Object;"
drchase@6134 224 + "Ljava/lang/Object;"
drchase@6134 225 + "Ljava/lang/Object;"
drchase@6134 226 + "Ljava/lang/Object;"
drchase@6134 227 + "Ljava/lang/Object;"
drchase@6134 228 + "Ljava/lang/Object;"
drchase@6134 229 + ")I", null, null);
drchase@6134 230 mv.visitCode();
drchase@6134 231 mv.visitLdcInsn(new Integer(3));
drchase@6134 232 mv.visitInsn(IRETURN);
drchase@6134 233 mv.visitMaxs(0, 0);
drchase@6134 234 mv.visitEnd();
drchase@6134 235 }
drchase@6134 236 cw.visitEnd();
drchase@6134 237 return cw.toByteArray();
drchase@6134 238 }
drchase@5800 239
drchase@6134 240 /**
drchase@6134 241 * The bytecodes for a class p/T defining a methods test() and test(11args)
drchase@6134 242 * that contain an invokeExact of a particular methodHandle, I.m.
drchase@6134 243 *
drchase@6134 244 * Test will be passed values that may imperfectly implement I,
drchase@6134 245 * and thus may in turn throw exceptions.
drchase@6134 246 *
drchase@5800 247 * @return
drchase@5800 248 * @throws Exception
drchase@5800 249 */
drchase@5800 250 public static byte[] bytesForT() throws Exception {
drchase@5800 251
drchase@6134 252 ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES
drchase@6134 253 | ClassWriter.COMPUTE_MAXS);
drchase@5800 254 MethodVisitor mv;
drchase@5800 255
drchase@6134 256 cw.visit(V1_8, ACC_PUBLIC + ACC_SUPER, "p/T", null, "java/lang/Object", null);
drchase@5800 257 {
drchase@5800 258 mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
drchase@5800 259 mv.visitCode();
drchase@5800 260 mv.visitVarInsn(ALOAD, 0);
drchase@5800 261 mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V");
drchase@5800 262 mv.visitInsn(RETURN);
drchase@6134 263 mv.visitMaxs(0, 0);
drchase@5800 264 mv.visitEnd();
drchase@5800 265 }
drchase@6134 266 // static int test(I)
drchase@5800 267 {
drchase@6134 268 mv = cw.visitMethod(ACC_PUBLIC + ACC_STATIC, "test", "(Lp/I;)I", null, null);
drchase@5800 269 mv.visitCode();
drchase@6134 270 mv.visitLdcInsn(new Handle(Opcodes.H_INVOKEINTERFACE, "p/I", "m", "()I"));
drchase@6134 271 mv.visitVarInsn(ALOAD, 0);
drchase@6134 272 mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/invoke/MethodHandle",
drchase@6134 273 "invokeExact", "(Lp/I;)I");
drchase@5800 274 mv.visitInsn(IRETURN);
drchase@6134 275 mv.visitMaxs(0, 0);
drchase@6134 276 mv.visitEnd();
drchase@6134 277 }
drchase@6134 278 // static int test(I,11args)
drchase@6134 279 {
drchase@6134 280 mv = cw.visitMethod(ACC_PUBLIC + ACC_STATIC, "test", "(Lp/I;BCSIJLjava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)I", null, null);
drchase@6134 281 mv.visitCode();
drchase@6134 282 mv.visitLdcInsn(new Handle(Opcodes.H_INVOKEINTERFACE, "p/I", "m", "(BCSIJLjava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)I"));
drchase@6134 283 mv.visitVarInsn(ALOAD, 0);
drchase@6134 284 mv.visitVarInsn(ILOAD, 1);
drchase@6134 285 mv.visitVarInsn(ILOAD, 2);
drchase@6134 286 mv.visitVarInsn(ILOAD, 3);
drchase@6134 287 mv.visitVarInsn(ILOAD, 4);
drchase@6134 288 mv.visitVarInsn(LLOAD, 5);
drchase@6134 289 mv.visitVarInsn(ALOAD, 7);
drchase@6134 290 mv.visitVarInsn(ALOAD, 8);
drchase@6134 291 mv.visitVarInsn(ALOAD, 9);
drchase@6134 292 mv.visitVarInsn(ALOAD, 10);
drchase@6134 293 mv.visitVarInsn(ALOAD, 11);
drchase@6134 294 mv.visitVarInsn(ALOAD, 12);
drchase@6134 295 mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/invoke/MethodHandle",
drchase@6134 296 "invokeExact", "(Lp/I;BCSIJLjava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)I");
drchase@6134 297 mv.visitInsn(IRETURN);
drchase@6134 298 mv.visitMaxs(0, 0);
drchase@5800 299 mv.visitEnd();
drchase@5800 300 }
drchase@5800 301 cw.visitEnd();
drchase@5800 302 return cw.toByteArray();
drchase@5800 303 }
drchase@5800 304
drchase@6134 305 private static void tryAndCheckThrown(
drchase@6134 306 List<Throwable> lt, byte[] dBytes, String what, Class<?> expected, String jar_name)
drchase@6134 307 throws Throwable {
drchase@6134 308 tryAndCheckThrown(lt, "p.D", dBytes, what, expected, jar_name);
drchase@6134 309 }
drchase@6134 310
drchase@6134 311 private static void tryAndCheckThrown(List<Throwable> lt, String d_name, byte[] dBytes, String what, Class<?> expected, String jar_name)
drchase@6134 312 throws Throwable {
drchase@6134 313
drchase@6134 314 System.out.println("Methodhandle invokeExact I.m() for instance of " + what);
drchase@6134 315 ByteClassLoader bcl1 = new ByteClassLoader(jar_name, readJarFiles, writeJarFiles);
drchase@5800 316 try {
drchase@6134 317 Class<?> d1 = bcl1.loadBytes(d_name, dBytes);
drchase@6134 318 Class<?> t1 = bcl1.loadBytes("p.T", bytesForT());
drchase@6134 319 invokeTest(t1, d1, expected, lt);
drchase@6134 320 } finally {
drchase@6134 321 // Not necessary for others -- all class files are written in this call.
drchase@6134 322 // (unless the VM crashes first).
drchase@6134 323 bcl1.close();
drchase@6134 324 }
drchase@6134 325
drchase@6134 326 System.out.println("Reflection invoke I.m() for instance of " + what);
drchase@6134 327 ByteClassLoader bcl3 = new ByteClassLoader(jar_name, readJarFiles, false);
drchase@6134 328 Class<?> d3 = bcl3.loadBytes(d_name, dBytes);
drchase@6134 329 Class<?> t3 = bcl3.loadClass("p.Treflect");
drchase@6134 330 invokeTest(t3, d3, expected, lt);
drchase@6134 331
drchase@6134 332 System.out.println("Bytecode invokeInterface I.m() for instance of " + what);
drchase@6134 333 ByteClassLoader bcl2 = new ByteClassLoader(jar_name, readJarFiles, false);
drchase@6134 334 Class<?> d2 = bcl2.loadBytes(d_name, dBytes);
drchase@6134 335 Class<?> t2 = bcl2.loadClass("p.Tdirect");
drchase@6134 336 badGoodBadGood(t2, d2, expected, lt);
drchase@6134 337 }
drchase@6134 338
drchase@6134 339 private static void invokeTest(Class<?> t, Class<?> d, Class<?> expected, List<Throwable> lt)
drchase@6134 340 throws Throwable {
drchase@6134 341 try {
drchase@6134 342 Method m = t.getMethod("test", p.I.class);
drchase@6134 343 Object o = d.newInstance();
drchase@6134 344 Object result = m.invoke(null, o);
drchase@6134 345 if (expected != null) {
drchase@6134 346 System.out.println("FAIL, Expected " + expected.getName()
drchase@6134 347 + " wrapped in InvocationTargetException, but nothing was thrown");
drchase@6134 348 lt.add(new Error("Exception " + expected.getName() + " was not thrown"));
drchase@6134 349 } else {
drchase@6134 350 System.out.println("PASS, saw expected return.");
drchase@6134 351 }
drchase@5800 352 } catch (InvocationTargetException e) {
drchase@5800 353 Throwable th = e.getCause();
drchase@6134 354 th.printStackTrace(System.out);
drchase@6134 355 if (expected != null) {
drchase@6134 356 if (expected.isInstance(th)) {
drchase@6134 357 System.out.println("PASS, saw expected exception (" + expected.getName() + ").");
drchase@6134 358 } else {
drchase@6134 359 System.out.println("FAIL, Expected " + expected.getName()
drchase@6134 360 + " wrapped in InvocationTargetException, saw " + th);
drchase@6134 361 lt.add(th);
drchase@6134 362 }
drchase@5800 363 } else {
drchase@6134 364 System.out.println("FAIL, expected no exception, saw " + th);
drchase@6134 365 lt.add(th);
drchase@5800 366 }
drchase@5800 367 }
drchase@6134 368 System.out.println();
drchase@6134 369 }
drchase@6134 370
drchase@6134 371 /* Many-arg versions of above */
drchase@6134 372 private static void tryAndCheckThrownMany(List<Throwable> lt, byte[] dBytes, String what, Class<?> expected)
drchase@6134 373 throws Throwable {
drchase@6134 374
drchase@6134 375 System.out.println("Methodhandle invokeExact I.m(11params) for instance of " + what);
drchase@6134 376 ByteClassLoader bcl1 = new ByteClassLoader("p.D", readJarFiles, false);
drchase@6134 377 try {
drchase@6134 378 Class<?> d1 = bcl1.loadBytes("p.D", dBytes);
drchase@6134 379 Class<?> t1 = bcl1.loadBytes("p.T", bytesForT());
drchase@6134 380 invokeTestMany(t1, d1, expected, lt);
drchase@6134 381 } finally {
drchase@6134 382 bcl1.close(); // Not necessary for others -- all class files are written in this call.
drchase@6134 383 }
drchase@6134 384
drchase@6134 385 {
drchase@6134 386 System.out.println("Bytecode invokeInterface I.m(11params) for instance of " + what);
drchase@6134 387 ByteClassLoader bcl2 = new ByteClassLoader("pD_m_pri_imp_pI", readJarFiles, false);
drchase@6134 388 Class<?> d2 = bcl2.loadBytes("p.D", dBytes);
drchase@6134 389 Class<?> t2 = bcl2.loadClass("p.Tdirect");
drchase@6134 390 badGoodBadGoodMany(t2, d2, expected, lt);
drchase@6134 391
drchase@6134 392 }
drchase@6134 393 {
drchase@6134 394 System.out.println("Reflection invokeInterface I.m(11params) for instance of " + what);
drchase@6134 395 ByteClassLoader bcl2 = new ByteClassLoader("pD_m_pri_imp_pI", readJarFiles, false);
drchase@6134 396 Class<?> d2 = bcl2.loadBytes("p.D", dBytes);
drchase@6134 397 Class<?> t2 = bcl2.loadClass("p.Treflect");
drchase@6134 398 invokeTestMany(t2, d2, expected, lt);
drchase@6134 399 }
drchase@6134 400 }
drchase@6134 401
drchase@6134 402 private static void invokeTestMany(Class<?> t, Class<?> d, Class<?> expected, List<Throwable> lt)
drchase@6134 403 throws Throwable {
drchase@6134 404 try {
drchase@6134 405 Method m = t.getMethod("test", p.I.class,
drchase@6134 406 Byte.TYPE, Character.TYPE, Short.TYPE, Integer.TYPE, Long.TYPE,
drchase@6134 407 Object.class, Object.class, Object.class,
drchase@6134 408 Object.class, Object.class, Object.class);
drchase@6134 409 Object o = d.newInstance();
drchase@6134 410 Byte b = 1;
drchase@6134 411 Character c = 2;
drchase@6134 412 Short s = 3;
drchase@6134 413 Integer i = 4;
drchase@6134 414 Long j = 5L;
drchase@6134 415 Object o1 = b;
drchase@6134 416 Object o2 = c;
drchase@6134 417 Object o3 = s;
drchase@6134 418 Object o4 = i;
drchase@6134 419 Object o5 = j;
drchase@6134 420 Object o6 = "6";
drchase@6134 421
drchase@6134 422 Object result = m.invoke(null, o, b, c, s, i, j,
drchase@6134 423 o1, o2, o3, o4, o5, o6);
drchase@6134 424 if (expected != null) {
drchase@6134 425 System.out.println("FAIL, Expected " + expected.getName()
drchase@6134 426 + " wrapped in InvocationTargetException, but nothing was thrown");
drchase@6134 427 lt.add(new Error("Exception " + expected.getName()
drchase@6134 428 + " was not thrown"));
drchase@6134 429 } else {
drchase@6134 430 System.out.println("PASS, saw expected return.");
drchase@6134 431 }
drchase@6134 432 } catch (InvocationTargetException e) {
drchase@6134 433 Throwable th = e.getCause();
drchase@6134 434 th.printStackTrace(System.out);
drchase@6134 435 if (expected != null) {
drchase@6134 436 if (expected.isInstance(th)) {
drchase@6134 437 System.out.println("PASS, saw expected exception ("
drchase@6134 438 + expected.getName() + ").");
drchase@6134 439 } else {
drchase@6134 440 System.out.println("FAIL, Expected " + expected.getName()
drchase@6134 441 + " wrapped in InvocationTargetException, saw " + th);
drchase@6134 442 lt.add(th);
drchase@6134 443 }
drchase@6134 444 } else {
drchase@6134 445 System.out.println("FAIL, expected no exception, saw " + th);
drchase@6134 446 lt.add(th);
drchase@6134 447 }
drchase@6134 448 }
drchase@6134 449 System.out.println();
drchase@6134 450 }
drchase@6134 451
drchase@6134 452 /**
drchase@6134 453 * This tests a peculiar idiom for tickling the bug on older VMs that lack
drchase@6134 454 * methodhandles. The bug (if not fixed) acts in the following way:
drchase@6134 455 *
drchase@6134 456 * When a broken receiver is passed to the first execution of an invokeinterface
drchase@6134 457 * bytecode, the illegal access is detected before the effects of resolution are
drchase@6134 458 * cached for later use, and so repeated calls with a broken receiver will always
drchase@6134 459 * throw the correct error.
drchase@6134 460 *
drchase@6134 461 * If, however, a good receiver is passed to the invokeinterface, the effects of
drchase@6134 462 * resolution will be successfully cached. A subsequent execution with a broken
drchase@6134 463 * receiver will reuse the cached information, skip the detailed resolution work,
drchase@6134 464 * and instead encounter a null pointer. By convention, that is the encoding for a
drchase@6134 465 * missing abstract method, and an AbstractMethodError is thrown -- not the expected
drchase@6134 466 * IllegalAccessError.
drchase@6134 467 *
drchase@6134 468 * @param t2 Test invocation class
drchase@6134 469 * @param d2 Test receiver class
drchase@6134 470 * @param expected expected exception type
drchase@6134 471 * @param lt list of unexpected throwables seen
drchase@6134 472 */
drchase@6134 473 private static void badGoodBadGood(Class<?> t2, Class<?> d2, Class<?> expected, List<Throwable> lt)
drchase@6134 474 throws Throwable {
drchase@6134 475 System.out.println(" Error input 1st time");
drchase@6134 476 invokeTest(t2, d2, expected, lt);
drchase@6134 477 System.out.println(" Good input (instance of Dok)");
drchase@6134 478 invokeTest(t2, Dok.class, null, lt);
drchase@6134 479 System.out.println(" Error input 2nd time");
drchase@6134 480 invokeTest(t2, d2, expected, lt);
drchase@6134 481 System.out.println(" Good input (instance of Dok)");
drchase@6134 482 invokeTest(t2, Dok.class, null, lt);
drchase@6134 483 }
drchase@6134 484
drchase@6134 485 private static void badGoodBadGoodMany(Class<?> t2, Class<?> d2, Class<?> expected, List<Throwable> lt)
drchase@6134 486 throws Throwable {
drchase@6134 487 System.out.println(" Error input 1st time");
drchase@6134 488 invokeTestMany(t2, d2, expected, lt);
drchase@6134 489 System.out.println(" Good input (instance of Dok)");
drchase@6134 490 invokeTestMany(t2, Dok.class, null, lt);
drchase@6134 491 System.out.println(" Error input 2nd time");
drchase@6134 492 invokeTestMany(t2, d2, expected, lt);
drchase@6134 493 System.out.println(" Good input (instance of Dok)");
drchase@6134 494 invokeTestMany(t2, Dok.class, null, lt);
drchase@5800 495 }
drchase@5800 496 }

mercurial