8157310: jdk.dynalink.linker.support.Lookup should have more checks before adding module read link
authorsundar
Fri, 20 May 2016 13:20:10 +0530
changeset 38491 777ad2adf246
parent 38490 8b30c52dc414
child 38492 5b094876c96a
8157310: jdk.dynalink.linker.support.Lookup should have more checks before adding module read link Reviewed-by: hannesw, attila
nashorn/src/jdk.dynalink/share/classes/jdk/dynalink/beans/CallerSensitiveDynamicMethod.java
nashorn/src/jdk.dynalink/share/classes/jdk/dynalink/linker/support/Lookup.java
--- a/nashorn/src/jdk.dynalink/share/classes/jdk/dynalink/beans/CallerSensitiveDynamicMethod.java	Thu May 19 19:46:39 2016 +0000
+++ b/nashorn/src/jdk.dynalink/share/classes/jdk/dynalink/beans/CallerSensitiveDynamicMethod.java	Fri May 20 13:20:10 2016 +0530
@@ -88,9 +88,11 @@
 import java.lang.invoke.MethodType;
 import java.lang.reflect.AccessibleObject;
 import java.lang.reflect.Constructor;
+import java.lang.reflect.Executable;
 import java.lang.reflect.Member;
 import java.lang.reflect.Method;
 import java.lang.reflect.Modifier;
+import java.lang.reflect.Module;
 import java.security.AccessControlContext;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
@@ -98,6 +100,9 @@
 import jdk.dynalink.SecureLookupSupplier;
 import jdk.dynalink.internal.AccessControlContextFactory;
 import jdk.dynalink.linker.support.Lookup;
+import jdk.internal.module.Modules;
+import jdk.internal.reflect.CallerSensitive;
+
 
 /**
  * A dynamic method bound to exactly one Java method or constructor that is caller sensitive. Since the target method is
@@ -159,13 +164,13 @@
                 GET_LOOKUP_CONTEXT);
 
         if(target instanceof Method) {
-            final MethodHandle mh = Lookup.unreflectCallerSensitive(lookup, (Method)target);
+            final MethodHandle mh = unreflect(lookup, (Method)target);
             if(Modifier.isStatic(((Member)target).getModifiers())) {
                 return StaticClassIntrospector.editStaticMethodHandle(mh);
             }
             return mh;
         }
-        return StaticClassIntrospector.editConstructorMethodHandle(Lookup.unreflectConstructorCallerSensitive(lookup,
+        return StaticClassIntrospector.editConstructorMethodHandle(unreflectConstructor(lookup,
                 (Constructor<?>)target));
     }
 
@@ -173,4 +178,59 @@
     boolean isConstructor() {
         return target instanceof Constructor;
     }
+
+    private static MethodHandle unreflect(final MethodHandles.Lookup lookup, final Method m) {
+        try {
+            return Lookup.unreflect(lookup, m);
+        } catch (final IllegalAccessError iae) {
+            if (addModuleRead(lookup, m)) {
+                try {
+                    return Lookup.unreflect(lookup, m);
+                } catch (final IllegalAccessError e2) {
+                    // fall through and throw original error as cause
+                }
+            }
+            throw iae;
+        }
+    }
+
+    private static MethodHandle unreflectConstructor(final MethodHandles.Lookup lookup, final Constructor<?> c) {
+        try {
+            return Lookup.unreflectConstructor(lookup, c);
+        } catch (final IllegalAccessError iae) {
+            if (addModuleRead(lookup, c)) {
+                try {
+                    return Lookup.unreflectConstructor(lookup, c);
+                } catch (final IllegalAccessError e2) {
+                    // fall through and throw original error as cause
+                }
+            }
+            throw iae;
+        }
+    }
+
+
+    private static boolean addModuleRead(final MethodHandles.Lookup lookup, final Executable e) {
+        // Don't add module read link if this is not a CallerSensitive member
+        if (!e.isAnnotationPresent(CallerSensitive.class)) {
+            return false;
+        }
+
+        // If the lookup is public lookup, don't bother adding module read link!
+        // public lookup cannot unreflect caller sensitives anyway!
+        if (lookup == MethodHandles.publicLookup()) {
+            return false;
+        }
+
+        // try to add missing module read from using module to declararing module!
+        final Class<?> declClass = e.getDeclaringClass();
+        final Module useModule = lookup.lookupClass().getModule();
+        final Module declModule = declClass.getModule();
+        if (useModule != null && declModule != null && declModule.isExported(declClass.getPackageName())) {
+            Modules.addReads(useModule, declModule);
+            return true;
+        }
+
+        return false;
+    }
 }
--- a/nashorn/src/jdk.dynalink/share/classes/jdk/dynalink/linker/support/Lookup.java	Thu May 19 19:46:39 2016 +0000
+++ b/nashorn/src/jdk.dynalink/share/classes/jdk/dynalink/linker/support/Lookup.java	Fri May 20 13:20:10 2016 +0530
@@ -91,7 +91,6 @@
 import java.lang.reflect.Field;
 import java.lang.reflect.Module;
 import java.lang.reflect.Method;
-import jdk.internal.module.Modules;
 
 /**
  * A wrapper around {@link java.lang.invoke.MethodHandles.Lookup} that masks
@@ -130,42 +129,6 @@
         return unreflect(lookup, m);
     }
 
-    private static boolean addModuleRead(final MethodHandles.Lookup lookup, final Executable e) {
-        // may be module read missing from a script class!
-        final Class<?> declClass = e.getDeclaringClass();
-        final Module from = lookup.lookupClass().getModule();
-        final Module to = declClass.getModule();
-        if (from != null && to != null) {
-            Modules.addReads(from, to);
-            return true;
-        }
-
-        return false;
-    }
-
-    /**
-     * Performs a {@link java.lang.invoke.MethodHandles.Lookup#unreflect(Method)}, of a caller sensitive method
-     * converting any encountered {@link IllegalAccessException} into an {@link IllegalAccessError}.
-     *
-     * @param lookup the lookup used to unreflect
-     * @param m the method to unreflect
-     * @return the unreflected method handle.
-     */
-    public static MethodHandle unreflectCallerSensitive(final MethodHandles.Lookup lookup, final Method m) {
-        try {
-            return unreflect(lookup, m);
-        } catch (final IllegalAccessError iae) {
-            if (addModuleRead(lookup, m)) {
-                try {
-                    return unreflect(lookup, m);
-                } catch (final IllegalAccessError e2) {
-                    // fall through and throw original error as cause
-                }
-            }
-            throw iae;
-        }
-    }
-
     /**
      * Performs a {@link java.lang.invoke.MethodHandles.Lookup#unreflect(Method)},
      * converting any encountered {@link IllegalAccessException} into an
@@ -267,29 +230,6 @@
     }
 
     /**
-     * Performs a caller sensitive {@link java.lang.invoke.MethodHandles.Lookup#unreflectConstructor(Constructor)}, converting any
-     * encountered {@link IllegalAccessException} into an {@link IllegalAccessError}.
-     *
-     * @param lookup the lookup used to unreflect
-     * @param c the constructor to unreflect
-     * @return the unreflected constructor handle.
-     */
-    public static MethodHandle unreflectConstructorCallerSensitive(final MethodHandles.Lookup lookup, final Constructor<?> c) {
-        try {
-            return unreflectConstructor(lookup, c);
-        } catch (final IllegalAccessError iae) {
-            if (addModuleRead(lookup, c)) {
-                try {
-                    return unreflectConstructor(lookup, c);
-                } catch (final IllegalAccessError e2) {
-                    // fall through and throw original error as cause
-                }
-            }
-            throw iae;
-        }
-    }
-
-    /**
      * Performs a {@link java.lang.invoke.MethodHandles.Lookup#unreflectConstructor(Constructor)},
      * converting any encountered {@link IllegalAccessException} into an
      * {@link IllegalAccessError}.