MHIllegalAccess.java revision 15491:6f390eafc676
1/* 2 * Copyright (c) 2013, 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 8022701 27 * @summary Illegal access exceptions via methodhandle invocations threw wrong error. 28 * @modules java.base/jdk.internal.org.objectweb.asm 29 * @compile -XDignore.symbol.file BogoLoader.java InvokeSeveralWays.java MHIllegalAccess.java MethodSupplier.java 30 * @run main/othervm MHIllegalAccess 31 */ 32 33import java.lang.reflect.InvocationTargetException; 34import java.util.HashMap; 35import java.util.HashSet; 36import jdk.internal.org.objectweb.asm.ClassWriter; 37import jdk.internal.org.objectweb.asm.MethodVisitor; 38import jdk.internal.org.objectweb.asm.ClassVisitor; 39import jdk.internal.org.objectweb.asm.Opcodes; 40 41public class MHIllegalAccess implements Opcodes { 42 43 public static void main(String args[]) throws Throwable { 44 System.out.println("Classpath is " + System.getProperty("java.class.path")); 45 System.out.println(); 46 47 /** 48 * Make method m be private to provoke an IllegalAccessError. 49 */ 50 BogoLoader.VisitorMaker privatize = new BogoLoader.VisitorMaker() { 51 public ClassVisitor make(ClassVisitor cv) { 52 return new ClassVisitor(Opcodes.ASM5, cv) { 53 public MethodVisitor visitMethod(int access, String name, String desc, 54 String signature, String[] exceptions) { 55 if (name.equals("m")) 56 access = (access | ACC_PRIVATE) & ~ (ACC_PUBLIC | ACC_PROTECTED); 57 return super.visitMethod(access, name, desc, signature, exceptions); 58 } 59 }; 60 } 61 }; 62 63 /** 64 * Rename method m as nemo to provoke a NoSuchMethodError. 65 */ 66 BogoLoader.VisitorMaker changeName = new BogoLoader.VisitorMaker() { 67 public ClassVisitor make(ClassVisitor cv) { 68 return new ClassVisitor(Opcodes.ASM5, cv) { 69 public MethodVisitor visitMethod(int access, String name, String desc, 70 String signature, String[] exceptions) { 71 if (name.equals("m")) 72 name = "nemo"; 73 return super.visitMethod(access, name, desc, signature, exceptions); 74 } 75 }; 76 } 77 }; 78 79 int failures = 0; 80 failures += testOneError(privatize, args, IllegalAccessError.class); 81 failures += testOneError(changeName, args, NoSuchMethodError.class); 82 if (failures > 0) { 83 System.out.println("Saw " + failures + " failures, see standard out for details"); 84 throw new Error("FAIL test"); 85 } 86 } 87 88 /** 89 * 90 * @param vm VisitorMaker, to be stored in a table and passed to a BogoLoader 91 * @param args A copy of the main args, to be passed on to InvokeSeveralWays.test 92 * @param expected The class of the exception that should be thrown after 93 * attempted invocation of MethodSupplier.m. 94 * @throws ClassNotFoundException 95 * @throws Throwable 96 */ 97 private static int testOneError(BogoLoader.VisitorMaker vm, String[] args, Class expected) throws ClassNotFoundException, Throwable { 98 HashMap<String, BogoLoader.VisitorMaker> replace = new HashMap<String, BogoLoader.VisitorMaker>(); 99 replace.put("MethodSupplier", vm); 100 101 HashSet<String> in_bogus = new HashSet<String>(); 102 in_bogus.add("InvokeSeveralWays"); 103 in_bogus.add("MyFunctionalInterface"); 104 in_bogus.add("Invoker"); 105 106 BogoLoader bl = new BogoLoader(in_bogus, replace); 107 Class<?> isw = bl.loadClass("InvokeSeveralWays"); 108 Object[] arg_for_args = new Object[2]; 109 arg_for_args[0] = args; 110 arg_for_args[1] = expected; 111 try { 112 Object result = isw.getMethod("test", String[].class, Class.class).invoke(null, arg_for_args); 113 return (Integer)result; 114 } catch (InvocationTargetException e) { 115 Throwable th = e.getCause(); 116 throw th == null ? e : th; 117 } 118 } 119} 120