DATACMNS-1181 - Adapt MethodHandle lookup of default methods in package-scoped interfaces to changes in Java 9.

We now attempt MethodHandle lookup with deep reflection capabilities via MethodHandles.privateLookupIn(…) to properly resolve default interface methods on interfaces with package-protected visibility. This API is only available in Java 9 so we need to rely on reflection.

Original pull request: #251.
This commit is contained in:
Mark Paluch
2017-09-28 17:21:05 +02:00
committed by Oliver Gierke
parent fc02b4fd08
commit b18989786f

View File

@@ -122,6 +122,9 @@ public class DefaultMethodInvokingMethodInterceptor implements MethodInterceptor
*/
ENCAPSULATED {
private final @Nullable Method privateLookupIn = ReflectionUtils.findMethod(MethodHandles.class,
"privateLookupIn", Class.class, Lookup.class);
/*
* (non-Javadoc)
* @see org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.MethodHandleLookup#lookup(java.lang.reflect.Method)
@@ -131,8 +134,8 @@ public class DefaultMethodInvokingMethodInterceptor implements MethodInterceptor
MethodType methodType = MethodType.methodType(method.getReturnType(), method.getParameterTypes());
return MethodHandles.lookup().findSpecial(method.getDeclaringClass(), method.getName(), methodType,
method.getDeclaringClass());
return getLookup(method.getDeclaringClass()).findSpecial(method.getDeclaringClass(), method.getName(),
methodType, method.getDeclaringClass());
}
/*
@@ -143,6 +146,21 @@ public class DefaultMethodInvokingMethodInterceptor implements MethodInterceptor
boolean isAvailable() {
return true;
}
private Lookup getLookup(Class<?> declaringClass) {
Lookup lookup = MethodHandles.lookup();
if (privateLookupIn == null) {
return lookup;
}
try {
return (Lookup) privateLookupIn.invoke(MethodHandles.class, declaringClass, lookup);
} catch (ReflectiveOperationException e) {
return lookup;
}
}
};
/**