8157310: jdk.dynalink.linker.support.Lookup should have more checks before adding module read link
Reviewed-by: hannesw, attila
This commit is contained in:
parent
9a8cbd6e1b
commit
c81faa1b04
@ -88,9 +88,11 @@ import java.lang.invoke.MethodHandles;
|
||||
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.CallSiteDescriptor;
|
||||
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 @@ class CallerSensitiveDynamicMethod extends SingleDynamicMethod {
|
||||
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 @@ class CallerSensitiveDynamicMethod extends SingleDynamicMethod {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -91,7 +91,6 @@ import java.lang.reflect.Executable;
|
||||
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 @@ public final class Lookup {
|
||||
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
|
||||
@ -266,29 +229,6 @@ public final class Lookup {
|
||||
return unreflectConstructor(lookup, c);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
|
Loading…
Reference in New Issue
Block a user