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/19 05:51:35 UTC

[groovy] branch danielsun/tweak-build updated (5713cba -> eb48c59)

This is an automated email from the ASF dual-hosted git repository.

sunlan pushed a change to branch danielsun/tweak-build
in repository https://gitbox.apache.org/repos/asf/groovy.git.


 discard 5713cba  Disable `SecurityTest.testChecksCreateClassLoaderPermissionForClassLoaderProtectedMethodAccess` for JDK16+
 discard eb1c547  Cache the special methods
 discard 621bddc  Disable `SecurityTest.testChecksCreateClassLoaderPermissionForClassLoaderProtectedMethodAccess` for JDK16+
     new 0a66186  Disable `SecurityTest.testChecksCreateClassLoaderPermissionForClassLoaderProtectedMethodAccess` for JDK16+
     new eb48c59  Cache special methods

This update added new revisions after undoing existing revisions.
That is to say, some revisions that were in the old version of the
branch are not in the new version.  This situation occurs
when a user --force pushes a change and generates a repository
containing something like this:

 * -- * -- B -- O -- O -- O   (5713cba)
            \
             N -- N -- N   refs/heads/danielsun/tweak-build (eb48c59)

You should already have received notification emails for all of the O
revisions, and so the following emails describe only the N revisions
from the common base, B.

Any revisions marked "omit" are not gone; other references still
refer to them.  Any revisions marked "discard" are gone forever.

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 src/main/java/groovy/lang/MetaClassImpl.java | 27 ++++++++++++++++++---------
 1 file changed, 18 insertions(+), 9 deletions(-)

[groovy] 02/02: Cache special methods

Posted by su...@apache.org.
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 eb48c592444667aada9d18f84c4f9b7d361971bd
Author: Daniel Sun <su...@apache.org>
AuthorDate: Sat Jun 19 13:49:34 2021 +0800

    Cache special methods
---
 src/main/java/groovy/lang/MetaClassImpl.java       | 47 +++++++++++++++++++---
 .../groovy/reflection/ReflectionUtils.java         | 38 ++++++++++-------
 2 files changed, 65 insertions(+), 20 deletions(-)

diff --git a/src/main/java/groovy/lang/MetaClassImpl.java b/src/main/java/groovy/lang/MetaClassImpl.java
index 83a0e1d..4e2d1e9 100644
--- a/src/main/java/groovy/lang/MetaClassImpl.java
+++ b/src/main/java/groovy/lang/MetaClassImpl.java
@@ -104,6 +104,7 @@ import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Comparator;
+import java.util.HashSet;
 import java.util.Iterator;
 import java.util.LinkedHashMap;
 import java.util.LinkedHashSet;
@@ -121,6 +122,7 @@ import static java.lang.Character.isUpperCase;
 import static org.apache.groovy.util.Arrays.concat;
 import static org.codehaus.groovy.ast.tools.GeneralUtils.inSamePackage;
 import static org.codehaus.groovy.reflection.ReflectionCache.isAssignableFrom;
+import static org.codehaus.groovy.reflection.ReflectionUtils.parameterTypeMatches;
 
 /**
  * Allows methods to be dynamically added to existing classes at runtime
@@ -1152,6 +1154,13 @@ public class MetaClassImpl implements MetaClass, MutableMetaClass {
         private MethodHolder() {}
     }
 
+    private static final ClassValue<Map<String, Set<Method>>> SPECIAL_METHODS_MAP = new ClassValue<Map<String, Set<Method>>>() {
+        @Override
+        protected Map<String, Set<Method>> computeValue(Class<?> type) {
+            return new ConcurrentHashMap<>(4);
+        }
+    };
+
     private Object doInvokeMethodFallback(Class sender, Object object, String methodName, Object[] originalArguments, boolean isCallToSuper, MissingMethodException mme) {
         MethodHandles.Lookup lookup = null;
         if (object instanceof GroovyObject) {
@@ -1163,7 +1172,8 @@ public class MetaClassImpl implements MetaClass, MutableMetaClass {
         final Class<?> receiverClass = object.getClass();
         if (isCallToSuper) {
             if (null == lookup) throw mme;
-            Method superMethod = findMethod(sender, methodName, originalArguments);
+            Class[] argTypes = MetaClassHelper.castArgumentsToClassArray(originalArguments);
+            Method superMethod = findMethod(sender, methodName, argTypes);
             if (null == superMethod) throw mme;
             MethodHandle superMethodHandle;
             try {
@@ -1171,6 +1181,7 @@ public class MetaClassImpl implements MetaClass, MutableMetaClass {
             } catch (IllegalAccessException e) {
                 throw mme;
             }
+            cacheMethod(sender, superMethod);
             try {
                 return superMethodHandle.bindTo(object).invokeWithArguments(originalArguments);
             } catch (Throwable t) {
@@ -1203,7 +1214,8 @@ public class MetaClassImpl implements MetaClass, MutableMetaClass {
                     throw mme;
                 }
             }
-            Method thisMethod = findMethod(receiverClass, methodName, originalArguments);
+            Class[] argTypes = MetaClassHelper.castArgumentsToClassArray(originalArguments);
+            Method thisMethod = findMethod(receiverClass, methodName, argTypes);
             if (null == thisMethod) throw mme;
             MethodHandle thisMethodHandle;
             try {
@@ -1211,6 +1223,7 @@ public class MetaClassImpl implements MetaClass, MutableMetaClass {
             } catch (IllegalAccessException e) {
                 throw mme;
             }
+            cacheMethod(receiverClass, thisMethod);
             try {
                 return thisMethodHandle.bindTo(object).invokeWithArguments(originalArguments);
             } catch (Throwable t) {
@@ -1219,10 +1232,34 @@ public class MetaClassImpl implements MetaClass, MutableMetaClass {
         }
     }
 
-    private static Method findMethod(Class clazz, String messageName, Object[] messageArguments) {
-        Class[] parameterTypes = MetaClassHelper.castArgumentsToClassArray(messageArguments);
+    private static void cacheMethod(Class clazz, Method method) {
+        Map<String, Set<Method>> methods = SPECIAL_METHODS_MAP.get(clazz);
+        methods.compute(method.getName(), (k, v) -> {
+            if (null == v) {
+                v = new HashSet<>();
+            }
+            v.add(method);
+            return v;
+        });
+    }
+
+    private static Method findMethod(Class clazz, String messageName, Class[] argTypes) {
+        Set<Method> methods = SPECIAL_METHODS_MAP.get(clazz).get(messageName);
+
+        if (null != methods) {
+            for (Method method : methods) {
+                if (method.getName().equals(messageName) && parameterTypeMatches(method.getParameterTypes(), argTypes)) {
+                    return method;
+                }
+            }
+        }
+
+        return doFindMethod(clazz, messageName, argTypes);
+    }
+
+    private static Method doFindMethod(Class clazz, String messageName, Class[] argTypes) {
         for (Class<?> c = clazz; null != c; c = c.getSuperclass()) {
-            List<Method> declaredMethodList = ReflectionUtils.getDeclaredMethods(c, messageName, parameterTypes);
+            List<Method> declaredMethodList = ReflectionUtils.getDeclaredMethods(c, messageName, argTypes);
             if (!declaredMethodList.isEmpty()) {
                 Method superMethod = declaredMethodList.get(0);
                 if (Modifier.isAbstract(superMethod.getModifiers())) {
diff --git a/src/main/java/org/codehaus/groovy/reflection/ReflectionUtils.java b/src/main/java/org/codehaus/groovy/reflection/ReflectionUtils.java
index e83b3d9..b87917c 100644
--- a/src/main/java/org/codehaus/groovy/reflection/ReflectionUtils.java
+++ b/src/main/java/org/codehaus/groovy/reflection/ReflectionUtils.java
@@ -145,35 +145,43 @@ public class ReflectionUtils {
     private static List<Method> doGetMethods(final Class<?> type, final String name, final Class<?>[] parameterTypes, final Function<? super Class<?>, ? extends Method[]> f) {
         List<Method> methodList = new LinkedList<>();
 
-        out:
         for (Method m : f.apply(type)) {
             if (!m.getName().equals(name)) {
                 continue;
             }
-
             Class<?>[] methodParameterTypes = m.getParameterTypes();
-            if (methodParameterTypes.length != parameterTypes.length) {
+            if (!parameterTypeMatches(methodParameterTypes, parameterTypes)) {
                 continue;
             }
 
-            for (int i = 0, n = methodParameterTypes.length; i < n; i += 1) {
-                Class<?> parameterType = TypeUtil.autoboxType(parameterTypes[i]);
-                if (null == parameterType) {
-                    continue out;
-                }
-
-                Class<?> methodParameterType = TypeUtil.autoboxType(methodParameterTypes[i]);
-                if (!methodParameterType.isAssignableFrom(parameterType)) {
-                    continue out;
-                }
-            }
-
             methodList.add(m);
         }
 
         return methodList;
     }
 
+    public static boolean parameterTypeMatches(final Class<?>[] parameterTypes, final Class<?>[] argTypes) {
+        if (parameterTypes.length != argTypes.length) {
+            return false;
+        }
+
+        for (int i = 0, n = parameterTypes.length; i < n; i += 1) {
+            Class<?> argType = argTypes[i];
+            Class<?> parameterType = parameterTypes[i];
+
+            if (null == argType) return false;
+            if (parameterType == argType) continue;
+
+            Class<?> boxedArgType = TypeUtil.autoboxType(argType);
+            Class<?> boxedParameterType = TypeUtil.autoboxType(parameterType);
+            if (!boxedParameterType.isAssignableFrom(boxedArgType)) {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
     public static boolean checkCanSetAccessible(final AccessibleObject accessibleObject, final Class<?> caller) {
         return VM_PLUGIN.checkCanSetAccessible(accessibleObject, caller);
     }

[groovy] 01/02: Disable `SecurityTest.testChecksCreateClassLoaderPermissionForClassLoaderProtectedMethodAccess` for JDK16+

Posted by su...@apache.org.
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 0a66186b3f02224c9efbf0867473f4b051ecf9d1
Author: Daniel Sun <su...@apache.org>
AuthorDate: Sat Jun 19 13:48:59 2021 +0800

    Disable `SecurityTest.testChecksCreateClassLoaderPermissionForClassLoaderProtectedMethodAccess` for JDK16+
---
 src/test/org/codehaus/groovy/reflection/SecurityTest.java | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/src/test/org/codehaus/groovy/reflection/SecurityTest.java b/src/test/org/codehaus/groovy/reflection/SecurityTest.java
index d466847..5f24859 100644
--- a/src/test/org/codehaus/groovy/reflection/SecurityTest.java
+++ b/src/test/org/codehaus/groovy/reflection/SecurityTest.java
@@ -241,6 +241,9 @@ public class SecurityTest extends GroovyTestCase {
 
 
     public void testChecksCreateClassLoaderPermissionForClassLoaderProtectedMethodAccess() throws Exception {
+        // Illegal access to java.lang.ClassLoader.defineClass(java.lang.String,java.nio.ByteBuffer,java.security.ProtectionDomain)
+        if (isAtLeastJdk("16.0")) return;
+
         cachedMethodUnderTest = createCachedMethod(ClassLoader.class, "defineClass", new Class[]{String.class, ByteBuffer.class, ProtectionDomain.class});
         forbidden = new Permissions();
         forbidden.add(new RuntimePermission("createClassLoader"));