From 2de23113188495ce1583acf0f1bef774987c8d35 Mon Sep 17 00:00:00 2001 From: Guice Team Date: Mon, 26 Oct 2020 14:59:29 -0700 Subject: [PATCH] Update `FactoryProvider2` to support Java 15. The private constructor used in looking up method handles has changed to take an extra parameter. This change update the code to look for both constructor signatures. PiperOrigin-RevId: 339124988 --- .../assistedinject/FactoryProvider2.java | 32 +++++++++++++++---- 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/extensions/assistedinject/src/com/google/inject/assistedinject/FactoryProvider2.java b/extensions/assistedinject/src/com/google/inject/assistedinject/FactoryProvider2.java index 19bf19a24b..6bdafbd037 100644 --- a/extensions/assistedinject/src/com/google/inject/assistedinject/FactoryProvider2.java +++ b/extensions/assistedinject/src/com/google/inject/assistedinject/FactoryProvider2.java @@ -900,13 +900,26 @@ protected Object initialValue() { findMethodHandlesLookupCxtor(); private static Constructor findMethodHandlesLookupCxtor() { - try { - Constructor cxtor = - MethodHandles.Lookup.class.getDeclaredConstructor(Class.class, int.class); + // Different JDK implementations have different constructors so look for a constructor that + // takes a class and an int first (openjdk-8, openjdk-11) and fallback to a constructor that + // takes two classes and an int (openjdk-15). + // TODO(b/171738889): Figure out a better way to handle this. + Constructor cxtor = findMethodHandlesLookupCxtor(Class.class, int.class); + if (cxtor == null) { + cxtor = findMethodHandlesLookupCxtor(Class.class, Class.class, int.class); + } + if (cxtor != null) { cxtor.setAccessible(true); - return cxtor; - } catch (ReflectiveOperationException ignored) { - // Ignore, the code falls back to a less-precise check if we can't create method handles. + } + return cxtor; + } + + private static Constructor findMethodHandlesLookupCxtor( + Class... parameterTypes) { + try { + return MethodHandles.Lookup.class.getDeclaredConstructor(parameterTypes); + } catch (NoSuchMethodException e) { + // Ignored if the constructor doesn't exist. return null; } } @@ -919,7 +932,12 @@ private static MethodHandle createMethodHandle(Method method, Object proxy) { int allModes = Modifier.PRIVATE | Modifier.STATIC /* package */ | Modifier.PUBLIC | Modifier.PROTECTED; try { - MethodHandles.Lookup lookup = methodHandlesLookupCxtor.newInstance(declaringClass, allModes); + MethodHandles.Lookup lookup; + if (methodHandlesLookupCxtor.getParameterCount() == 2) { + lookup = methodHandlesLookupCxtor.newInstance(declaringClass, allModes); + } else { + lookup = methodHandlesLookupCxtor.newInstance(declaringClass, null, allModes); + } method.setAccessible(true); return lookup.unreflectSpecial(method, declaringClass).bindTo(proxy); } catch (ReflectiveOperationException roe) {