This is an automated email from the ASF dual-hosted git repository. sunlan pushed a commit to branch danielsun/tweak-build in repository https://gitbox.apache.org/repos/asf/groovy.git
commit 9aad592f551f7c82c3439284bf5e70a58d357c74 Author: Daniel Sun <sun...@apache.org> AuthorDate: Sun Jun 13 21:42:33 2021 +0800 Add java16 vmplugin --- .../codehaus/groovy/vmplugin/VMPluginFactory.java | 1 + .../org/codehaus/groovy/vmplugin/v16/Java16.java | 104 +++++++++++++++++++++ .../vmplugin/v16/PluginDefaultGroovyMethods.java | 29 ++++++ .../org/codehaus/groovy/vmplugin/v8/Java8.java | 1 + .../org/codehaus/groovy/vmplugin/v9/Java9.java | 17 +--- 5 files changed, 140 insertions(+), 12 deletions(-) diff --git a/src/main/java/org/codehaus/groovy/vmplugin/VMPluginFactory.java b/src/main/java/org/codehaus/groovy/vmplugin/VMPluginFactory.java index 7e2d66b..d3ac172 100644 --- a/src/main/java/org/codehaus/groovy/vmplugin/VMPluginFactory.java +++ b/src/main/java/org/codehaus/groovy/vmplugin/VMPluginFactory.java @@ -39,6 +39,7 @@ public class VMPluginFactory { private static final Logger LOGGER = Logger.getLogger(VMPluginFactory.class.getName()); private static final Map<BigDecimal, String> PLUGIN_MAP = Maps.of( // Note: list the vm plugin entries in *descending* order: + new BigDecimal("16"), "org.codehaus.groovy.vmplugin.v16.Java16", new BigDecimal("10"), "org.codehaus.groovy.vmplugin.v10.Java10", new BigDecimal("9"), "org.codehaus.groovy.vmplugin.v9.Java9", new BigDecimal("1.8"), "org.codehaus.groovy.vmplugin.v8.Java8" diff --git a/src/main/java/org/codehaus/groovy/vmplugin/v16/Java16.java b/src/main/java/org/codehaus/groovy/vmplugin/v16/Java16.java new file mode 100644 index 0000000..1733f0f --- /dev/null +++ b/src/main/java/org/codehaus/groovy/vmplugin/v16/Java16.java @@ -0,0 +1,104 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.codehaus.groovy.vmplugin.v16; + +import groovy.lang.GroovyRuntimeException; +import org.codehaus.groovy.vmplugin.v10.Java10; + +import java.lang.invoke.MethodHandles; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * Additional Java 16 based functions will be added here as needed. + */ +public class Java16 extends Java10 { + private final Class<?>[] PLUGIN_DGM; + + public Java16() { + super(); + List<Class<?>> dgmClasses = new ArrayList<>(); + Collections.addAll(dgmClasses, super.getPluginDefaultGroovyMethods()); + dgmClasses.add(PluginDefaultGroovyMethods.class); + PLUGIN_DGM = dgmClasses.toArray(new Class<?>[0]); + } + + @Override + protected MethodHandles.Lookup newLookup(final Class<?> declaringClass) { + return of(declaringClass); + } + + public static MethodHandles.Lookup of(final Class<?> declaringClass) { + try { + // All proxy classes are not open for reflective access in Java SE 16 + // See also https://www.oracle.com/java/technologies/javase/16-relnotes.html + if (Proxy.isProxyClass(declaringClass)) { + return MethodHandles.lookup().in(declaringClass); + } + + final Method privateLookup = getPrivateLookup(); + if (privateLookup != null) { + MethodHandles.Lookup caller = MethodHandles.lookup(); + Class<?> callerClass = caller.lookupClass(); + Module callerModule = callerClass.getModule(); + Module targetModule = declaringClass.getModule(); + if (targetModule != callerModule) { + if (targetModule.isNamed()) { + String pn = declaringClass.getPackageName(); + if (!targetModule.isOpen(pn, callerModule)) { + return MethodHandles.lookup().in(declaringClass); + } + } + } + + return (MethodHandles.Lookup) privateLookup.invoke(null, declaringClass, caller); + } + return getLookupConstructor().newInstance(declaringClass, MethodHandles.Lookup.PRIVATE).in(declaringClass); + } catch (final IllegalAccessException | InstantiationException e) { + throw new IllegalArgumentException(e); + } catch (final InvocationTargetException e) { + throw new GroovyRuntimeException(e); + } + } + + @Override + public Object getInvokeSpecialHandle(Method method, Object receiver) { + final Class<?> receiverType = receiver.getClass(); + try { + MethodHandles.Lookup lookup = newLookup(receiverType); + return lookup.unreflectSpecial(method, receiverType).bindTo(receiver); + } catch (ReflectiveOperationException e) { + return new GroovyRuntimeException(e); + } + } + + @Override + public Class<?>[] getPluginDefaultGroovyMethods() { + return PLUGIN_DGM; + } + + @Override + public int getVersion() { + return 16; + } +} diff --git a/src/main/java/org/codehaus/groovy/vmplugin/v16/PluginDefaultGroovyMethods.java b/src/main/java/org/codehaus/groovy/vmplugin/v16/PluginDefaultGroovyMethods.java new file mode 100644 index 0000000..232ef8b --- /dev/null +++ b/src/main/java/org/codehaus/groovy/vmplugin/v16/PluginDefaultGroovyMethods.java @@ -0,0 +1,29 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.codehaus.groovy.vmplugin.v16; + +/** + * Defines new Groovy methods which appear on normal JDK 16 + * classes inside the Groovy environment. + * + * @since 4.0.0 + */ +public class PluginDefaultGroovyMethods { + +} diff --git a/src/main/java/org/codehaus/groovy/vmplugin/v8/Java8.java b/src/main/java/org/codehaus/groovy/vmplugin/v8/Java8.java index 3f54df0..87a6d40 100644 --- a/src/main/java/org/codehaus/groovy/vmplugin/v8/Java8.java +++ b/src/main/java/org/codehaus/groovy/vmplugin/v8/Java8.java @@ -652,6 +652,7 @@ public class Java8 implements VMPlugin { @Override public Object invokeHandle(Object handle, Object[] args) throws Throwable { + if (handle instanceof Throwable) throw (Throwable) handle; MethodHandle mh = (MethodHandle) handle; return mh.invokeWithArguments(args); } diff --git a/src/main/java/org/codehaus/groovy/vmplugin/v9/Java9.java b/src/main/java/org/codehaus/groovy/vmplugin/v9/Java9.java index bf476e4..bb050d8 100644 --- a/src/main/java/org/codehaus/groovy/vmplugin/v9/Java9.java +++ b/src/main/java/org/codehaus/groovy/vmplugin/v9/Java9.java @@ -42,7 +42,6 @@ import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Member; import java.lang.reflect.Method; import java.lang.reflect.Modifier; -import java.lang.reflect.Proxy; import java.math.BigInteger; import java.net.URI; import java.util.ArrayList; @@ -170,22 +169,16 @@ public class Java9 extends Java8 { return of(declaringClass); } - private static Constructor<MethodHandles.Lookup> getLookupConstructor() { + protected static Constructor<MethodHandles.Lookup> getLookupConstructor() { return LookupHolder.LOOKUP_Constructor; } - private static Method getPrivateLookup() { + protected static Method getPrivateLookup() { return LookupHolder.PRIVATE_LOOKUP; } public static MethodHandles.Lookup of(final Class<?> declaringClass) { try { - // All proxy classes are not open for reflective access in Java SE 16 - // See also https://www.oracle.com/java/technologies/javase/16-relnotes.html - if (Proxy.isProxyClass(declaringClass)) { - return MethodHandles.lookup().in(declaringClass); - } - final Method privateLookup = getPrivateLookup(); if (privateLookup != null) { return (MethodHandles.Lookup) privateLookup.invoke(null, declaringClass, MethodHandles.lookup()); @@ -361,8 +354,8 @@ public class Java9 extends Java8 { private static List<CachedMethod> getMetaMethods(CachedMethod metaMethod, Class<?>[] params, Class<?> sc, boolean declared) { String metaMethodName = metaMethod.getName(); List<Method> optionalMethodList = declared - ? ReflectionUtils.getDeclaredMethods(sc, metaMethodName, params) - : ReflectionUtils.getMethods(sc, metaMethodName, params); + ? ReflectionUtils.getDeclaredMethods(sc, metaMethodName, params) + : ReflectionUtils.getMethods(sc, metaMethodName, params); return optionalMethodList.stream().map(CachedMethod::new).collect(Collectors.toList()); } @@ -1820,4 +1813,4 @@ public class Java9 extends Java8 { "sun.util.xml" }; } -} +} \ No newline at end of file