8157310: jdk.dynalink.linker.support.Lookup should have more checks before adding module read link
Reviewed-by: hannesw, attila
--- 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}.