You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by su...@apache.org on 2021/06/14 07:08:12 UTC
[groovy] branch danielsun/tweak-build updated: GROOVY-10138:
[JDK16] Failed to invoke default method of proxy
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
The following commit(s) were added to refs/heads/danielsun/tweak-build by this push:
new 2c5c26b GROOVY-10138: [JDK16] Failed to invoke default method of proxy
2c5c26b is described below
commit 2c5c26b3075d2f17d44c8109605db7acb019963c
Author: Daniel Sun <su...@apache.org>
AuthorDate: Mon Jun 14 15:07:31 2021 +0800
GROOVY-10138: [JDK16] Failed to invoke default method of proxy
---
.../org/codehaus/groovy/vmplugin/v16/Java16.java | 26 ++++++++++++++-----
.../groovy/vmplugin/v16/ProxyMethodHandle.java | 30 ++++++++++++++++++++++
.../org/codehaus/groovy/vmplugin/v8/Java8.java | 1 -
3 files changed, 49 insertions(+), 8 deletions(-)
diff --git a/src/main/java/org/codehaus/groovy/vmplugin/v16/Java16.java b/src/main/java/org/codehaus/groovy/vmplugin/v16/Java16.java
index 1733f0f..8d2e1bb 100644
--- a/src/main/java/org/codehaus/groovy/vmplugin/v16/Java16.java
+++ b/src/main/java/org/codehaus/groovy/vmplugin/v16/Java16.java
@@ -21,6 +21,7 @@ package org.codehaus.groovy.vmplugin.v16;
import groovy.lang.GroovyRuntimeException;
import org.codehaus.groovy.vmplugin.v10.Java10;
+import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
@@ -50,12 +51,6 @@ public class Java16 extends Java10 {
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();
@@ -85,14 +80,31 @@ public class Java16 extends Java10 {
public Object getInvokeSpecialHandle(Method method, Object receiver) {
final Class<?> receiverType = receiver.getClass();
try {
+ if (method.isDefault() && Proxy.isProxyClass(receiverType)) {
+ return new ProxyMethodHandle((Proxy) receiver, method);
+ }
+
MethodHandles.Lookup lookup = newLookup(receiverType);
- return lookup.unreflectSpecial(method, receiverType).bindTo(receiver);
+ if (MethodHandles.Lookup.PRIVATE == lookup.lookupModes()) {
+ return lookup.unreflectSpecial(method, receiverType).bindTo(receiver);
+ }
+ return lookup.unreflect(method).bindTo(receiver);
} catch (ReflectiveOperationException e) {
return new GroovyRuntimeException(e);
}
}
@Override
+ public Object invokeHandle(Object handle, Object[] args) throws Throwable {
+ if (handle instanceof ProxyMethodHandle) {
+ return ((ProxyMethodHandle) handle).invokeWithArguments(args);
+ }
+ if (handle instanceof Throwable) throw (Throwable) handle;
+ MethodHandle mh = (MethodHandle) handle;
+ return mh.invokeWithArguments(args);
+ }
+
+ @Override
public Class<?>[] getPluginDefaultGroovyMethods() {
return PLUGIN_DGM;
}
diff --git a/src/main/java/org/codehaus/groovy/vmplugin/v16/ProxyMethodHandle.java b/src/main/java/org/codehaus/groovy/vmplugin/v16/ProxyMethodHandle.java
new file mode 100644
index 0000000..d6a1e39
--- /dev/null
+++ b/src/main/java/org/codehaus/groovy/vmplugin/v16/ProxyMethodHandle.java
@@ -0,0 +1,30 @@
+package org.codehaus.groovy.vmplugin.v16;
+
+import org.codehaus.groovy.GroovyBugError;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+
+class ProxyMethodHandle {
+ private static final Method INVOKE_DEFAULT_METHOD;
+ static {
+ try {
+ INVOKE_DEFAULT_METHOD = InvocationHandler.class.getDeclaredMethod("invokeDefault", Object.class, Method.class, Object[].class);
+ } catch (NoSuchMethodException e) {
+ throw new GroovyBugError(e);
+ }
+ }
+
+ private final Proxy proxy;
+ private final Method method;
+
+ ProxyMethodHandle(Proxy proxy, Method method) {
+ this.proxy = proxy;
+ this.method = method;
+ }
+
+ Object invokeWithArguments(Object... arguments) throws Throwable {
+ return INVOKE_DEFAULT_METHOD.invoke(null, proxy, method, arguments);
+ }
+}
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 87a6d40..3f54df0 100644
--- a/src/main/java/org/codehaus/groovy/vmplugin/v8/Java8.java
+++ b/src/main/java/org/codehaus/groovy/vmplugin/v8/Java8.java
@@ -652,7 +652,6 @@ 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);
}