< prev index next >

test/java/lang/invoke/AccessControlTest.java

Print this page
rev 13059 : 8130227: Extend MethodHandle APIs

@@ -1,7 +1,7 @@
 /*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 only, as
  * published by the Free Software Foundation.

@@ -223,10 +223,35 @@
             }
             if (verbosity >= 2)
                 System.out.println(this+" willAccess "+lc+" m1="+m1+" m2="+m2+" => "+((m2 & m1) != 0));
             return (m2 & m1) != 0;
         }
+
+        /** Predict the success or failure of accessing this class. */
+        public boolean willAccessClass(Class<?> c2, boolean load) {
+            Class<?> c1 = lookupClass();
+            if (load && c1.getClassLoader() == null) {
+                return false;
+            }
+            LookupCase lc = this.in(c2);
+            int m1 = lc.lookupModes();
+            boolean r = false;
+            if (m1 == 0) {
+                r = false;
+            } else {
+                int m2 = fixMods(c2.getModifiers());
+                if ((m2 & PUBLIC) != 0) {
+                    r = true;
+                } else if ((m1 & PACKAGE) != 0 && c1.getPackage() == c2.getPackage()) {
+                    r = true;
+                }
+            }
+            if (verbosity >= 2) {
+                System.out.println(this+" willAccessClass "+lc+" c1="+c1+" c2="+c2+" => "+r);
+            }
+            return r;
+        }
     }
 
     private static Class<?> topLevelClass(Class<?> cls) {
         Class<?> c = cls;
         for (Class<?> ec; (ec = c.getEnclosingClass()) != null; )

@@ -340,10 +365,12 @@
             for (int targetAccess : ACCESS_CASES) {
                 MethodType methodType = methodType(void.class);
                 Method method = targetMethod(targetClass, targetAccess, methodType);
                 // Try to access target method from various contexts.
                 for (LookupCase sourceCase : CASES) {
+                    testOneAccess(sourceCase, method, "findClass");
+                    testOneAccess(sourceCase, method, "accessClass");
                     testOneAccess(sourceCase, method, "find");
                     testOneAccess(sourceCase, method, "unreflect");
                 }
             }
         }

@@ -354,15 +381,23 @@
 
     private void testOneAccess(LookupCase sourceCase, Method method, String kind) {
         Class<?> targetClass = method.getDeclaringClass();
         String methodName = method.getName();
         MethodType methodType = methodType(method.getReturnType(), method.getParameterTypes());
-        boolean willAccess = sourceCase.willAccess(method);
+        boolean isFindOrAccessClass = "findClass".equals(kind) || "accessClass".equals(kind);
+        boolean willAccess = isFindOrAccessClass ?
+                sourceCase.willAccessClass(targetClass, "findClass".equals(kind)) : sourceCase.willAccess(method);
         boolean didAccess = false;
         ReflectiveOperationException accessError = null;
         try {
             switch (kind) {
+            case "accessClass":
+                sourceCase.lookup().accessClass(targetClass);
+                break;
+            case "findClass":
+                sourceCase.lookup().findClass(targetClass.getName());
+                break;
             case "find":
                 if ((method.getModifiers() & Modifier.STATIC) != 0)
                     sourceCase.lookup().findStatic(targetClass, methodName, methodType);
                 else
                     sourceCase.lookup().findVirtual(targetClass, methodName, methodType);

@@ -376,12 +411,12 @@
             didAccess = true;
         } catch (ReflectiveOperationException ex) {
             accessError = ex;
         }
         if (willAccess != didAccess) {
-            System.out.println(sourceCase+" => "+targetClass.getSimpleName()+"."+methodName+methodType);
-            System.out.println("fail on "+method+" ex="+accessError);
+            System.out.println(sourceCase+" => "+targetClass.getSimpleName()+(isFindOrAccessClass?"":"."+methodName+methodType));
+            System.out.println("fail "+(isFindOrAccessClass?kind:"on "+method)+" ex="+accessError);
             assertEquals(willAccess, didAccess);
         }
         testCount++;
         if (!didAccess)  testCountFails++;
     }
< prev index next >