Repository: groovy
Updated Branches:
  refs/heads/master f5b3e41ae -> 3cb1a25c8


GROOVY-7330: Incorrect dynamic proxy creation from map when there are default 
methods (closes #785)


Project: http://git-wip-us.apache.org/repos/asf/groovy/repo
Commit: http://git-wip-us.apache.org/repos/asf/groovy/commit/3cb1a25c
Tree: http://git-wip-us.apache.org/repos/asf/groovy/tree/3cb1a25c
Diff: http://git-wip-us.apache.org/repos/asf/groovy/diff/3cb1a25c

Branch: refs/heads/master
Commit: 3cb1a25c8ccb9998d9201e759fe6e26c967405e8
Parents: f5b3e41
Author: Paul King <[email protected]>
Authored: Fri Aug 17 17:49:50 2018 +1000
Committer: Paul King <[email protected]>
Committed: Sun Aug 19 16:56:52 2018 +1000

----------------------------------------------------------------------
 .../groovy/runtime/ConversionHandler.java       |  8 ++-
 .../runtime/InterfaceConversionMapTest.java     | 54 ++++++++++++++++++++
 2 files changed, 60 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/groovy/blob/3cb1a25c/src/main/java/org/codehaus/groovy/runtime/ConversionHandler.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/codehaus/groovy/runtime/ConversionHandler.java 
b/src/main/java/org/codehaus/groovy/runtime/ConversionHandler.java
index 328b503..6ea07b2 100644
--- a/src/main/java/org/codehaus/groovy/runtime/ConversionHandler.java
+++ b/src/main/java/org/codehaus/groovy/runtime/ConversionHandler.java
@@ -32,6 +32,7 @@ import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.lang.reflect.Modifier;
 import java.lang.reflect.Proxy;
+import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
 
 /**
@@ -99,10 +100,9 @@ public abstract class ConversionHandler implements 
InvocationHandler, Serializab
      * @see InvocationHandler#invoke(java.lang.Object, 
java.lang.reflect.Method, java.lang.Object[])
      */
     public Object invoke(final Object proxy, Method method, Object[] args) 
throws Throwable {
-        if (handleCache != null && isDefaultMethod(method)) {
+        if (handleCache != null && isDefaultMethod(method) && 
!defaultOverridden(method)) {
             final VMPlugin plugin = VMPluginFactory.getPlugin();
             Object handle = handleCache.computeIfAbsent(method, m -> 
plugin.getInvokeSpecialHandle(m, proxy));
-
             return plugin.invokeHandle(handle, args);
         }
 
@@ -128,6 +128,10 @@ public abstract class ConversionHandler implements 
InvocationHandler, Serializab
         }
     }
 
+    private boolean defaultOverridden(Method method) {
+        return delegate instanceof Map && ((Map) 
delegate).containsKey(method.getName());
+    }
+
     protected boolean isDefaultMethod(Method method) {
         return ((method.getModifiers() & (Modifier.ABSTRACT | Modifier.PUBLIC 
| Modifier.STATIC)) ==
                 Modifier.PUBLIC) && method.getDeclaringClass().isInterface();

http://git-wip-us.apache.org/repos/asf/groovy/blob/3cb1a25c/src/test/org/codehaus/groovy/runtime/InterfaceConversionMapTest.java
----------------------------------------------------------------------
diff --git 
a/src/test/org/codehaus/groovy/runtime/InterfaceConversionMapTest.java 
b/src/test/org/codehaus/groovy/runtime/InterfaceConversionMapTest.java
new file mode 100644
index 0000000..5c67bd0
--- /dev/null
+++ b/src/test/org/codehaus/groovy/runtime/InterfaceConversionMapTest.java
@@ -0,0 +1,54 @@
+/*
+ *  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.runtime;
+
+import groovy.lang.GroovyShell;
+import org.codehaus.groovy.control.CompilerConfiguration;
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.util.Map;
+
+public class InterfaceConversionMapTest {
+
+    private final GroovyShell shell;
+
+    public InterfaceConversionMapTest() {
+        final CompilerConfiguration cc = new CompilerConfiguration();
+        cc.setTargetBytecode(CompilerConfiguration.JDK8);
+        shell = new GroovyShell(cc);
+    }
+
+    // GROOVY-7330
+    @Test
+    public void testMapToProxy() {
+        final Map map = (Map) shell.evaluate("[x: {10}, y: {20}]");
+        final SomeInterface si = DefaultGroovyMethods.asType(map, 
SomeInterface.class);
+        Assert.assertEquals(20, si.y());
+        Assert.assertEquals(10, si.x());
+    }
+
+    public interface SomeInterface {
+        default int x() {
+            return 1;
+        }
+
+        int y();
+    }
+}

Reply via email to