Github user blackdrag commented on a diff in the pull request: https://github.com/apache/groovy/pull/811#discussion_r225299922 --- Diff: src/main/java/org/codehaus/groovy/vmplugin/v9/Java9.java --- @@ -18,14 +18,78 @@ */ package org.codehaus.groovy.vmplugin.v9; +import org.codehaus.groovy.GroovyBugError; import org.codehaus.groovy.vmplugin.v8.Java8; +import java.lang.invoke.MethodHandles; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + /** - * Java 9 based functions will be added here if needed. + * Additional Java 9 based functions will be added here as needed. */ public class Java9 extends Java8 { + + private static class LookupHolder { + private static final Method PRIVATE_LOOKUP; + private static final Constructor<MethodHandles.Lookup> LOOKUP_Constructor; + static { + Constructor<MethodHandles.Lookup> lookup = null; + Method privateLookup = null; + try { // java 9 + privateLookup = MethodHandles.class.getMethod("privateLookupIn", Class.class, MethodHandles.Lookup.class); + } catch (final NoSuchMethodException e) { // java 8 + try { + lookup = MethodHandles.Lookup.class.getDeclaredConstructor(Class.class, Integer.TYPE); + if (!lookup.isAccessible()) { + lookup.setAccessible(true); + } + } catch (final NoSuchMethodException ex) { + throw new IllegalStateException("Incompatible JVM", e); + } + } + PRIVATE_LOOKUP = privateLookup; + LOOKUP_Constructor = lookup; + } + } + + private static Constructor<MethodHandles.Lookup> getLookupConstructor() { + return LookupHolder.LOOKUP_Constructor; + } + + private static Method getPrivateLookup() { + return LookupHolder.PRIVATE_LOOKUP; + } + + public static MethodHandles.Lookup of(final Class<?> declaringClass) { + try { + if (getPrivateLookup() != null) { + return MethodHandles.Lookup.class.cast(getPrivateLookup().invoke(null, declaringClass, MethodHandles.lookup())); + } + return getLookupConstructor().newInstance(declaringClass, MethodHandles.Lookup.PRIVATE).in(declaringClass); --- End diff -- If PRIVATE_LOOKUP lookup never fails as I think, then LOOKUP_Constructor will be always the same. Not sure if "in" (https://docs.oracle.com/javase/9/docs/api/java/lang/invoke/MethodHandles.Lookup.html#in-java.lang.Class-) then can still do something useful.
---