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 /** 26 * @test 27 * @bug 8022718 28 * @summary Runtime accessibility checking: protected class, if extended, should be accessible from another package 29 * @modules java.base/jdk.internal.org.objectweb.asm 30 * @compile -XDignore.symbol.file BogoLoader.java MethodInvoker.java Test.java anotherpkg/MethodSupplierOuter.java 31 * @run main/othervm Test 32 */ 33 34 import java.lang.reflect.InvocationTargetException; 35 import java.lang.reflect.Method; 36 import java.util.HashMap; 37 import java.util.HashSet; 38 import jdk.internal.org.objectweb.asm.ClassWriter; 39 import jdk.internal.org.objectweb.asm.MethodVisitor; 40 import jdk.internal.org.objectweb.asm.ClassVisitor; 41 import jdk.internal.org.objectweb.asm.Opcodes; 42 43 interface MyFunctionalInterface { 44 45 void invokeMethodReference(); 46 } 47 48 class MakeProtected implements BogoLoader.VisitorMaker, Opcodes { 49 50 final boolean whenVisitInner; 51 52 MakeProtected(boolean when_visit_inner) { 53 super(); 54 whenVisitInner = when_visit_inner; 55 } 56 57 public ClassVisitor make(ClassVisitor cv) { 58 return new ClassVisitor(Opcodes.ASM5, cv) { 59 60 @Override 61 public void visitInnerClass(String name, String outerName, 62 String innerName, int access) { 63 if (whenVisitInner) { 64 int access_ = (ACC_PROTECTED | access) & ~(ACC_PRIVATE | ACC_PUBLIC); 65 System.out.println("visitInnerClass: name = " + name 66 + ", outerName = " + outerName 67 + ", innerName = " + innerName 68 + ", access original = 0x" + Integer.toHexString(access) 69 + ", access modified to 0x" + Integer.toHexString(access_)); 70 access = access_; 71 } 72 super.visitInnerClass(name, outerName, innerName, access); 73 } 74 }; 75 } 76 }; 77 78 public class Test { 79 80 public static void main(String argv[]) throws Exception, Throwable { 81 BogoLoader.VisitorMaker makeProtectedNop = new MakeProtected(false); 82 BogoLoader.VisitorMaker makeProtectedMod = new MakeProtected(true); 83 84 int errors = 0; 85 errors += tryModifiedInvocation(makeProtectedNop); 86 errors += tryModifiedInvocation(makeProtectedMod); 87 88 if (errors > 0) { 89 throw new Error("FAIL; there were errors"); 90 } 91 } 92 93 private static int tryModifiedInvocation(BogoLoader.VisitorMaker makeProtected) 94 throws Throwable, ClassNotFoundException { 95 HashMap<String, BogoLoader.VisitorMaker> replace 96 = new HashMap<String, BogoLoader.VisitorMaker>(); 97 replace.put("anotherpkg.MethodSupplierOuter$MethodSupplier", makeProtected); 98 HashSet<String> in_bogus = new HashSet<String>(); 99 in_bogus.add("MethodInvoker"); 100 in_bogus.add("MyFunctionalInterface"); 101 in_bogus.add("anotherpkg.MethodSupplierOuter"); // seems to be never loaded 102 in_bogus.add("anotherpkg.MethodSupplierOuter$MethodSupplier"); 103 104 BogoLoader bl = new BogoLoader(in_bogus, replace); 105 try { 106 Class<?> isw = bl.loadClass("MethodInvoker"); 107 Method meth = isw.getMethod("invoke"); 108 Object result = meth.invoke(null); 109 } catch (Throwable th) { 110 System.out.flush(); 111 Thread.sleep(250); // Let Netbeans get its I/O sorted out. 112 th.printStackTrace(); 113 System.err.flush(); 114 Thread.sleep(250); // Let Netbeans get its I/O sorted out. 115 return 1; 116 } 117 return 0; 118 } 119 }