From f49c8c0db163f7f0201c2fea95a1614911f8438e Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Thu, 28 Sep 2017 13:02:28 +0200 Subject: [PATCH] Fix encapsulated default method lookup on interfaces #614 Use MethodHandles.privateLookupIn() instead of plain MethodHandles.lookup() to enable private lookups on Java 9. --- .../redis/internal/DefaultMethods.java | 30 +++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/lambdaworks/redis/internal/DefaultMethods.java b/src/main/java/com/lambdaworks/redis/internal/DefaultMethods.java index c59dc48c79..135af6606c 100644 --- a/src/main/java/com/lambdaworks/redis/internal/DefaultMethods.java +++ b/src/main/java/com/lambdaworks/redis/internal/DefaultMethods.java @@ -82,13 +82,39 @@ boolean isAvailable() { */ ENCAPSULATED { + Method privateLookupIn = findBridgeMethod(); + @Override MethodHandle lookup(Method method) throws ReflectiveOperationException { 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()); + } + + private Method findBridgeMethod() { + + try { + return MethodHandles.class.getDeclaredMethod("privateLookupIn", Class.class, Lookup.class); + } catch (ReflectiveOperationException e) { + return null; + } + } + + private Lookup getLookup(Class declaringClass) { + + Lookup lookup = MethodHandles.lookup(); + + if (privateLookupIn != null) { + try { + return (Lookup) privateLookupIn.invoke(null, declaringClass, lookup); + } catch (ReflectiveOperationException e) { + return lookup; + } + } + + return lookup; } @Override