Skip to content
This repository has been archived by the owner. It is now read-only.
Permalink
Browse files
8251538: Modernize and lint Dynalink code
Reviewed-by: sundar
  • Loading branch information
szegedi committed Aug 28, 2020
1 parent 3af532e commit 85eca9be051b4bfcdb90af2bf1d9acd1281172b0
Show file tree
Hide file tree
Showing 24 changed files with 80 additions and 187 deletions.
@@ -269,8 +269,7 @@ public String toString() {
final String mt = methodType.toString();
final String l = getLookupPrivileged().toString();
final String o = operation.toString();
final StringBuilder b = new StringBuilder(o.length() + mt.length() + 1 + l.length());
return b.append(o).append(mt).append('@').append(l).toString();
return o + mt + '@' + l;
}

private void assertChangeInvariants(final CallSiteDescriptor changed, final String caller) {
@@ -132,12 +132,9 @@ T get(final Class<?> clazz) {
final T newV = computeValue(clazz);
assert newV != null;

final Boolean canReferenceDirectly = AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
@Override
public Boolean run() {
return InternalTypeUtilities.canReferenceDirectly(classLoader, clazz.getClassLoader());
}
}, GET_CLASS_LOADER_CONTEXT);
final Boolean canReferenceDirectly = AccessController.doPrivileged(
(PrivilegedAction<Boolean>) () -> InternalTypeUtilities.canReferenceDirectly(classLoader, clazz.getClassLoader()),
GET_CLASS_LOADER_CONTEXT);

// If allowed to strongly reference, put it in the fast map
if(canReferenceDirectly) {
@@ -213,8 +213,7 @@ public LinkerServices getLinkerServices() {

private MethodHandle createRelinkAndInvokeMethod(final RelinkableCallSite callSite, final int relinkCount) {
// Make a bound MH of invoke() for this linker and call site
final MethodHandle boundRelinker = MethodHandles.insertArguments(RELINK, 0, this, callSite, Integer.valueOf(
relinkCount));
final MethodHandle boundRelinker = MethodHandles.insertArguments(RELINK, 0, this, callSite, relinkCount);
// Make a MH that gathers all arguments to the invocation into an Object[]
final MethodType type = callSite.getDescriptor().getMethodType();
final MethodHandle collectingRelinker = boundRelinker.asCollector(Object[].class, type.parameterCount());
@@ -471,12 +471,9 @@ private List<GuardingDynamicLinker> discoverAutoLoadLinkers() {
}

private static ClassLoader getThreadContextClassLoader() {
return AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() {
@Override
public ClassLoader run() {
return Thread.currentThread().getContextClassLoader();
}
}, GET_CLASS_LOADER_CONTEXT);
return AccessController.doPrivileged(
(PrivilegedAction<ClassLoader>) () -> Thread.currentThread().getContextClassLoader(),
GET_CLASS_LOADER_CONTEXT);
}

private static void addClasses(final Set<Class<? extends GuardingDynamicLinker>> knownLinkerClasses,
@@ -246,7 +246,7 @@ public boolean equals(final Object obj) {
@Override
public int hashCode() {
return baseOperation.hashCode() + 31 * Arrays.hashCode(namespaces);
};
}

/**
* Returns the string representation of this namespace operation. Defined to
@@ -93,10 +93,10 @@ final class TypeConverterFactory {
private final ConversionComparator[] comparators;
private final MethodTypeConversionStrategy autoConversionStrategy;

private final ClassValue<ClassMap<MethodHandle>> converterMap = new ClassValue<ClassMap<MethodHandle>>() {
private final ClassValue<ClassMap<MethodHandle>> converterMap = new ClassValue<>() {
@Override
protected ClassMap<MethodHandle> computeValue(final Class<?> sourceType) {
return new ClassMap<MethodHandle>(getClassLoader(sourceType)) {
return new ClassMap<>(getClassLoader(sourceType)) {
@Override
protected MethodHandle computeValue(final Class<?> targetType) {
try {
@@ -111,10 +111,10 @@ protected MethodHandle computeValue(final Class<?> targetType) {
}
};

private final ClassValue<ClassMap<MethodHandle>> converterIdentityMap = new ClassValue<ClassMap<MethodHandle>>() {
private final ClassValue<ClassMap<MethodHandle>> converterIdentityMap = new ClassValue<>() {
@Override
protected ClassMap<MethodHandle> computeValue(final Class<?> sourceType) {
return new ClassMap<MethodHandle>(getClassLoader(sourceType)) {
return new ClassMap<>(getClassLoader(sourceType)) {
@Override
protected MethodHandle computeValue(final Class<?> targetType) {
if(!canAutoConvert(sourceType, targetType)) {
@@ -129,10 +129,10 @@ protected MethodHandle computeValue(final Class<?> targetType) {
}
};

private final ClassValue<ClassMap<Boolean>> canConvert = new ClassValue<ClassMap<Boolean>>() {
private final ClassValue<ClassMap<Boolean>> canConvert = new ClassValue<>() {
@Override
protected ClassMap<Boolean> computeValue(final Class<?> sourceType) {
return new ClassMap<Boolean>(getClassLoader(sourceType)) {
return new ClassMap<>(getClassLoader(sourceType)) {
@Override
protected Boolean computeValue(final Class<?> targetType) {
try {
@@ -148,12 +148,7 @@ protected Boolean computeValue(final Class<?> targetType) {
};

private static ClassLoader getClassLoader(final Class<?> clazz) {
return AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() {
@Override
public ClassLoader run() {
return clazz.getClassLoader();
}
}, GET_CLASS_LOADER_CONTEXT);
return AccessController.doPrivileged((PrivilegedAction<ClassLoader>) clazz::getClassLoader, GET_CLASS_LOADER_CONTEXT);
}

/**
@@ -63,10 +63,9 @@ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
import java.lang.invoke.MethodHandle;
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.Field;
import java.lang.reflect.Member;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Arrays;
@@ -172,7 +171,7 @@ private static String decapitalize(final String str) {
return str;
}

final char c[] = str.toCharArray();
final char[] c = str.toCharArray();
c[0] = Character.toLowerCase(c0);
return new String(c);
}
@@ -232,8 +231,8 @@ void setPropertyGetter(final String name, final MethodHandle handle, final Valid
setPropertyGetter(name, new SimpleDynamicMethod(handle, clazz, name), validationType);
}

private void addMember(final String name, final AccessibleObject ao, final Map<String, DynamicMethod> methodMap) {
addMember(name, createDynamicMethod(ao), methodMap);
private void addMember(final String name, final Executable m, final Map<String, DynamicMethod> methodMap) {
addMember(name, createDynamicMethod(m), methodMap);
}

private void addMember(final String name, final SingleDynamicMethod method, final Map<String, DynamicMethod> methodMap) {
@@ -252,9 +251,9 @@ private void addMember(final String name, final SingleDynamicMethod method, fina
* @param name the common name of the reflective members.
* @return a dynamic method representing all the specified reflective members.
*/
static DynamicMethod createDynamicMethod(final Iterable<? extends AccessibleObject> members, final Class<?> clazz, final String name) {
static DynamicMethod createDynamicMethod(final Iterable<? extends Executable> members, final Class<?> clazz, final String name) {
DynamicMethod dynMethod = null;
for(final AccessibleObject method: members) {
for(final Executable method: members) {
dynMethod = mergeMethods(createDynamicMethod(method), dynMethod, clazz, name);
}
return dynMethod;
@@ -267,7 +266,7 @@ static DynamicMethod createDynamicMethod(final Iterable<? extends AccessibleObje
* @param m the reflective member
* @return the single dynamic method representing the reflective member
*/
private static SingleDynamicMethod createDynamicMethod(final AccessibleObject m) {
private static SingleDynamicMethod createDynamicMethod(final Executable m) {
if (m.isAnnotationPresent(CallerSensitive.class)) {
// Method has @CallerSensitive annotation
return new CallerSensitiveDynamicMethod(m);
@@ -282,8 +281,7 @@ private static SingleDynamicMethod createDynamicMethod(final AccessibleObject m)
return new CallerSensitiveDynamicMethod(m);
}
// Proceed with non-caller sensitive
final Member member = (Member)m;
return new SimpleDynamicMethod(mh, member.getDeclaringClass(), member.getName(), m instanceof Constructor);
return new SimpleDynamicMethod(mh, m.getDeclaringClass(), m.getName(), m instanceof Constructor);
}

/**
@@ -294,7 +292,7 @@ private static SingleDynamicMethod createDynamicMethod(final AccessibleObject m)
* @param m the method or constructor
* @return the method handle
*/
private static MethodHandle unreflectSafely(final AccessibleObject m) {
private static MethodHandle unreflectSafely(final Executable m) {
if(m instanceof Method) {
final Method reflMethod = (Method)m;
final MethodHandle handle = Lookup.PUBLIC.unreflect(reflMethod);
@@ -326,8 +324,6 @@ private static DynamicMethod mergeMethods(final SingleDynamicMethod method, fina
@Override
public GuardedInvocation getGuardedInvocation(final LinkRequest request, final LinkerServices linkerServices)
throws Exception {
final CallSiteDescriptor callSiteDescriptor = request.getCallSiteDescriptor();

final MissingMemberHandlerFactory missingMemberHandlerFactory;
final LinkerServices directLinkerServices;
if (linkerServices instanceof LinkerServicesWithMissingMemberHandlerFactory) {
@@ -436,14 +432,6 @@ private GuardedInvocationComponent createNoSuchMemberHandler(
return getClassGuardedInvocationComponent(handler, type);
}

static final <T> List<T> pop(final List<T> l) {
return l.subList(1, l.size());
}

MethodHandle getClassGuard(final CallSiteDescriptor desc) {
return getClassGuard(desc.getMethodType());
}

MethodHandle getClassGuard(final MethodType type) {
return Guards.asType(classGuard, type);
}
@@ -814,7 +802,7 @@ private static void assertParameterCount(final CallSiteDescriptor descriptor, fi
}
}

private static MethodHandle GET_PROPERTY_GETTER_HANDLE = MethodHandles.dropArguments(privateLookup.findOwnSpecial(
private static final MethodHandle GET_PROPERTY_GETTER_HANDLE = MethodHandles.dropArguments(privateLookup.findOwnSpecial(
"getPropertyGetterHandle", Object.class, Object.class), 1, Object.class);
private final MethodHandle getPropertyGetterHandle = GET_PROPERTY_GETTER_HANDLE.bindTo(this);

@@ -842,7 +830,7 @@ private MethodHandle getPropertySetterHandle(final CallSiteDescriptor setterDesc
return getDynamicMethodInvocation(setterDescriptor, linkerServices, String.valueOf(id), propertySetters);
}

private static MethodHandle GET_DYNAMIC_METHOD = MethodHandles.dropArguments(privateLookup.findOwnSpecial(
private static final MethodHandle GET_DYNAMIC_METHOD = MethodHandles.dropArguments(privateLookup.findOwnSpecial(
"getDynamicMethod", Object.class, Object.class), 1, Object.class);
private final MethodHandle getDynamicMethod = GET_DYNAMIC_METHOD.bindTo(this);

@@ -873,21 +861,21 @@ DynamicMethod getDynamicMethod(final String name) {
* @return getter with same name, declared on the most generic superclass/interface of the declaring class
*/
private static Method getMostGenericGetter(final Method getter) {
return getMostGenericGetter(getter.getName(), getter.getReturnType(), getter.getDeclaringClass());
return getMostGenericGetter(getter.getName(), getter.getDeclaringClass());
}

private static Method getMostGenericGetter(final String name, final Class<?> returnType, final Class<?> declaringClass) {
private static Method getMostGenericGetter(final String name, final Class<?> declaringClass) {
if(declaringClass == null) {
return null;
}
// Prefer interfaces
for(final Class<?> itf: declaringClass.getInterfaces()) {
final Method itfGetter = getMostGenericGetter(name, returnType, itf);
final Method itfGetter = getMostGenericGetter(name, itf);
if(itfGetter != null) {
return itfGetter;
}
}
final Method superGetter = getMostGenericGetter(name, returnType, declaringClass.getSuperclass());
final Method superGetter = getMostGenericGetter(name, declaringClass.getSuperclass());
if(superGetter != null) {
return superGetter;
}
@@ -93,17 +93,6 @@ class AccessibleMembersLookup {
lookupAccessibleMembers(clazz);
}

/**
* Returns an accessible method equivalent of a method.
*
* @param m the method whose accessible equivalent is requested.
* @return the accessible equivalent for the method (can be the same as the passed in method), or null if there is
* no accessible method equivalent.
*/
Method getAccessibleMethod(final Method m) {
return m == null ? null : methods.get(new MethodSignature(m));
}

Collection<Method> getMethods() {
return methods.values();
}
@@ -230,9 +219,8 @@ private void lookupAccessibleMembers(final Class<?> clazz) {
// If we reach here, the class is either not public, or it is in a restricted package. Alternatively, it is
// public, but some of its methods claim that their declaring class is non-public. We'll try superclasses
// and implemented interfaces then looking for public ones.
final Class<?>[] interfaces = clazz.getInterfaces();
for(int i = 0; i < interfaces.length; i++) {
lookupAccessibleMembers(interfaces[i]);
for (final Class<?> itf: clazz.getInterfaces()) {
lookupAccessibleMembers(itf);
}
final Class<?> superclass = clazz.getSuperclass();
if(superclass != null) {
@@ -158,7 +158,7 @@ private static MethodHandle dropObjectArguments(final MethodHandle m, final int

private enum CollectionType {
ARRAY, LIST, MAP
};
}

private GuardedInvocationComponent getElementGetter(final ComponentLinkRequest req) throws Exception {
final CallSiteDescriptor callSiteDescriptor = req.getDescriptor();
@@ -241,7 +241,7 @@ private static Object getTypedName(final Object name, final boolean isMap, final
// Convert the key to a number if we're working with a list or array
if (!isMap && name != null) {
final Integer integer = convertKeyToInteger(name, linkerServices);
if (integer == null || integer.intValue() < 0) {
if (integer == null || integer < 0) {
// key is not a non-negative integer, it can never address an
// array or list element
return INVALID_NAME;
@@ -133,7 +133,7 @@ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* method.</p>
*/
public class BeansLinker implements GuardingDynamicLinker {
private static final ClassValue<TypeBasedGuardingDynamicLinker> linkers = new ClassValue<TypeBasedGuardingDynamicLinker>() {
private static final ClassValue<TypeBasedGuardingDynamicLinker> linkers = new ClassValue<>() {
@Override
protected TypeBasedGuardingDynamicLinker computeValue(final Class<?> clazz) {
// If ClassValue.put() were public, we could just pre-populate with these known mappings...
@@ -63,10 +63,8 @@ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
import java.lang.invoke.MethodHandle;
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.security.AccessControlContext;
@@ -76,8 +74,6 @@ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
import jdk.dynalink.SecureLookupSupplier;
import jdk.dynalink.internal.AccessControlContextFactory;
import jdk.dynalink.linker.support.Lookup;
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
@@ -90,21 +86,18 @@ class CallerSensitiveDynamicMethod extends SingleDynamicMethod {
AccessControlContextFactory.createAccessControlContext(
SecureLookupSupplier.GET_LOOKUP_PERMISSION_NAME);

// Typed as "AccessibleObject" as it can be either a method or a constructor.
// If we were Java8-only, we could use java.lang.reflect.Executable
private final AccessibleObject target;
private final Executable target;
private final MethodType type;

CallerSensitiveDynamicMethod(final AccessibleObject target) {
CallerSensitiveDynamicMethod(final Executable target) {
super(getName(target));
this.target = target;
this.type = getMethodType(target);
}

private static String getName(final AccessibleObject target) {
final Member m = (Member)target;
private static String getName(final Executable m) {
final boolean constructor = m instanceof Constructor;
return getMethodNameWithSignature(getMethodType(target), constructor ? m.getName() :
return getMethodNameWithSignature(getMethodType(m), constructor ? m.getName() :
getClassAndMethodName(m.getDeclaringClass(), m.getName()), !constructor);
}

@@ -113,12 +106,11 @@ MethodType getMethodType() {
return type;
}

private static MethodType getMethodType(final AccessibleObject ao) {
final boolean isMethod = ao instanceof Method;
final Class<?> rtype = isMethod ? ((Method)ao).getReturnType() : ((Constructor<?>)ao).getDeclaringClass();
final Class<?>[] ptypes = isMethod ? ((Method)ao).getParameterTypes() : ((Constructor<?>)ao).getParameterTypes();
private static MethodType getMethodType(final Executable m) {
final boolean isMethod = m instanceof Method;
final Class<?> rtype = isMethod ? ((Method)m).getReturnType() : ((Constructor<?>)m).getDeclaringClass();
final Class<?>[] ptypes = m.getParameterTypes();
final MethodType type = MethodType.methodType(rtype, ptypes);
final Member m = (Member)ao;
return type.insertParameterTypes(0,
isMethod ?
Modifier.isStatic(m.getModifiers()) ?
@@ -129,18 +121,18 @@ private static MethodType getMethodType(final AccessibleObject ao) {

@Override
boolean isVarArgs() {
return target instanceof Method ? ((Method)target).isVarArgs() : ((Constructor<?>)target).isVarArgs();
return target.isVarArgs();
}

@Override
MethodHandle getTarget(final CallSiteDescriptor desc) {
final MethodHandles.Lookup lookup = AccessController.doPrivileged(
(PrivilegedAction<MethodHandles.Lookup>)()->desc.getLookup(),
(PrivilegedAction<MethodHandles.Lookup>)desc::getLookup,
GET_LOOKUP_CONTEXT);

if(target instanceof Method) {
final MethodHandle mh = unreflect(lookup, (Method)target);
if(Modifier.isStatic(((Member)target).getModifiers())) {
if(Modifier.isStatic(target.getModifiers())) {
return StaticClassIntrospector.editStaticMethodHandle(mh);
}
return mh;

0 comments on commit 85eca9b

Please sign in to comment.