tapestry-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From thiag...@apache.org
Subject tapestry-5 git commit: TAP5-2582: Service creation for Hibernate Session results in ClassFormatError: Duplicate method name&signature
Date Fri, 03 Nov 2017 02:10:40 GMT
Repository: tapestry-5
Updated Branches:
  refs/heads/5.4.x e226f86ac -> d7cc7c7da


TAP5-2582: Service creation for Hibernate Session results in
ClassFormatError: Duplicate method name&signature

Project: http://git-wip-us.apache.org/repos/asf/tapestry-5/repo
Commit: http://git-wip-us.apache.org/repos/asf/tapestry-5/commit/d7cc7c7d
Tree: http://git-wip-us.apache.org/repos/asf/tapestry-5/tree/d7cc7c7d
Diff: http://git-wip-us.apache.org/repos/asf/tapestry-5/diff/d7cc7c7d

Branch: refs/heads/5.4.x
Commit: d7cc7c7daed3e8d38472d211ceecfa2218793503
Parents: e226f86
Author: Thiago H. de Paula Figueiredo <thiago@arsmachina.com.br>
Authored: Fri Nov 3 00:09:53 2017 -0200
Committer: Thiago H. de Paula Figueiredo <thiago@arsmachina.com.br>
Committed: Fri Nov 3 00:09:53 2017 -0200

----------------------------------------------------------------------
 .../internal/plastic/PlasticClassImpl.java      | 124 +++++++++++++++++--
 .../tapestry5/plastic/MethodDescription.java    |  15 +++
 .../apache/tapestry5/plastic/PlasticClass.java  |  11 ++
 tapestry-ioc/build.gradle                       |   6 +-
 .../tapestry5/ioc/internal/ModuleImpl.java      |   9 +-
 .../AspectInterceptorBuilderImplSpec.groovy     |   2 +-
 .../tapestry5/ioc/internal/AdviceModule.java    |  21 ++++
 7 files changed, 173 insertions(+), 15 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/d7cc7c7d/plastic/src/main/java/org/apache/tapestry5/internal/plastic/PlasticClassImpl.java
----------------------------------------------------------------------
diff --git a/plastic/src/main/java/org/apache/tapestry5/internal/plastic/PlasticClassImpl.java
b/plastic/src/main/java/org/apache/tapestry5/internal/plastic/PlasticClassImpl.java
index 264825a..9683e1c 100644
--- a/plastic/src/main/java/org/apache/tapestry5/internal/plastic/PlasticClassImpl.java
+++ b/plastic/src/main/java/org/apache/tapestry5/internal/plastic/PlasticClassImpl.java
@@ -621,11 +621,37 @@ public class PlasticClassImpl extends Lockable implements PlasticClass,
Internal
 
         introduceInterface(interfaceType);
 
-        for (Method m : interfaceType.getMethods())
+        // TAP5-2582: avoiding adding/delegating the same method more than once
+//        for (Method m : interfaceType.getMethods())
+//        {
+//            introduceMethod(m).delegateTo(field);
+//        }
+        
+        Map<MethodSignature, MethodDescription> map = createMethodSignatureMap(interfaceType);
+        for (MethodSignature methodSignature : map.keySet())
         {
-            introduceMethod(m).delegateTo(field);
+            introduceMethod(map.get(methodSignature)).delegateTo(field);
         }
+        
+        return this;
+    }
+    
+    @Override
+    public PlasticClass proxyInterface(Class interfaceType, PlasticMethod method)
+    {
+        check();
 
+        assert method != null;
+
+        introduceInterface(interfaceType);
+
+        // TAP5-2582: avoiding adding/delegating the same method more than once
+        Map<MethodSignature, MethodDescription> map = createMethodSignatureMap(interfaceType);
+        for (MethodSignature methodSignature : map.keySet())
+        {
+            introduceMethod(map.get(methodSignature)).delegateTo(method);
+        }
+        
         return this;
     }
 
@@ -1410,7 +1436,7 @@ public class PlasticClassImpl extends Lockable implements PlasticClass,
Internal
 
         if (!interfaceType.isInterface())
             throw new IllegalArgumentException(String.format(
-                    "Class %s is not an interface; ony interfaces may be introduced.", interfaceType.getName()));
+                    "Class %s is not an interface; only interfaces may be introduced.", interfaceType.getName()));
 
         String interfaceName = nameCache.toInternalName(interfaceType);
 
@@ -1431,14 +1457,19 @@ public class PlasticClassImpl extends Lockable implements PlasticClass,
Internal
         addClassAnnotations(interfaceClassNode);
 
         Set<PlasticMethod> introducedMethods = new HashSet<PlasticMethod>();
-
-        for (Method m : interfaceType.getMethods())
+        
+        Map<MethodSignature, MethodDescription> map = createMethodSignatureMap(interfaceType);
+        
+        // for (Method m : interfaceType.getMethods())
+	for (MethodSignature methodSignature : map.keySet())
         {
-            MethodDescription description = new MethodDescription(m);
+            // MethodDescription description = new MethodDescription(m);
+            final MethodDescription description = map.get(methodSignature);
 
-            if (!isMethodImplemented(description) && !isDefaultMethod(m))
+            if (!isMethodImplemented(description) && !isDefaultMethod(methodSignature.method))
             {
-                introducedMethods.add(introduceMethod(m));
+                // introducedMethods.add(introduceMethod(m));
+                introducedMethods.add(introduceMethod(description));
             }
         }
 
@@ -1447,6 +1478,83 @@ public class PlasticClassImpl extends Lockable implements PlasticClass,
Internal
         return introducedMethods;
     }
 
+    private Map<MethodSignature, MethodDescription> createMethodSignatureMap(Class
interfaceType) {
+	// TAP-2582: preprocessing the method list so we don't add duplicated
+        // methods, something that happens when an interface has superinterfaces
+        // and they define the same method signature.
+        // In addition, we collect all the thrown checked exceptions, just in case.
+        Map<MethodSignature, MethodDescription> map = new HashMap<MethodSignature,
MethodDescription>();
+        for (Method m : interfaceType.getMethods())
+        {
+            final MethodSignature methodSignature = new MethodSignature(m);
+            final MethodDescription newMethodDescription = new MethodDescription(m);
+            if (!map.containsKey(methodSignature)) 
+            {
+		map.put(methodSignature, newMethodDescription);
+            }
+            else 
+            {
+        	if (newMethodDescription.checkedExceptionTypes != null && newMethodDescription.checkedExceptionTypes.length
> 0)
+        	{
+        	    final MethodDescription methodDescription = map.get(methodSignature);
+                    final Set<String> checkedExceptionTypes = new HashSet<String>();
+                    checkedExceptionTypes.addAll(Arrays.asList(methodDescription.checkedExceptionTypes));
+                    checkedExceptionTypes.addAll(Arrays.asList(newMethodDescription.checkedExceptionTypes));
+                    map.put(methodSignature, new MethodDescription(
+                	    methodDescription, 
+                	    checkedExceptionTypes.toArray(new String[checkedExceptionTypes.size()])));
+        	}
+            }
+        }
+	return map;
+    }
+    
+    final private static class MethodSignature implements Comparable<MethodSignature>{
+	
+	final private Method method;
+	final private String name;
+	final private Class<?>[] parameterTypes;
+	
+	public MethodSignature(Method method) {
+	    this.method = method;
+	    this.name = method.getName();
+	    this.parameterTypes = method.getParameterTypes();
+	}
+
+	@Override
+	public int hashCode() {
+	    final int prime = 31;
+	    int result = 1;
+	    result = prime * result + Arrays.hashCode(parameterTypes);
+	    result = prime * result + ((name == null) ? 0 : name.hashCode());
+	    return result;
+	}
+
+	@Override
+	public boolean equals(Object obj) {
+	    if (this == obj)
+		return true;
+	    if (obj == null)
+		return false;
+	    if (getClass() != obj.getClass())
+		return false;
+	    MethodSignature other = (MethodSignature) obj;
+	    if (!Arrays.equals(parameterTypes, other.parameterTypes))
+		return false;
+	    if (name == null) {
+		if (other.name != null)
+		    return false;
+	    } else if (!name.equals(other.name))
+		return false;
+	    return true;
+	}
+
+	@Override
+	public int compareTo(MethodSignature o) {
+	    return method.getName().compareTo(o.method.getName());
+	}
+    }
+
     @Override
     public PlasticClass addToString(final String toStringValue)
     {

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/d7cc7c7d/plastic/src/main/java/org/apache/tapestry5/plastic/MethodDescription.java
----------------------------------------------------------------------
diff --git a/plastic/src/main/java/org/apache/tapestry5/plastic/MethodDescription.java b/plastic/src/main/java/org/apache/tapestry5/plastic/MethodDescription.java
index e0b7d2a..5f8b88f 100644
--- a/plastic/src/main/java/org/apache/tapestry5/plastic/MethodDescription.java
+++ b/plastic/src/main/java/org/apache/tapestry5/plastic/MethodDescription.java
@@ -72,6 +72,21 @@ public class MethodDescription implements Comparable<MethodDescription>
     {
         this(Modifier.PUBLIC, returnType, methodName, argumentTypes, null, null);
     }
+    
+    /**
+     * Convenience constructor for copying a MethodDescription with
+     * different exception types.
+     * @since 5.4.4
+     */
+    public MethodDescription(MethodDescription description, String[] checkedExceptionTypes)
+    {
+	this.argumentTypes = description.argumentTypes;
+	this.checkedExceptionTypes = checkedExceptionTypes;
+	this.genericSignature = description.genericSignature;
+	this.methodName = description.methodName;
+	this.modifiers = description.modifiers;
+	this.returnType = description.returnType;
+    }
 
     /**
      * @param modifiers

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/d7cc7c7d/plastic/src/main/java/org/apache/tapestry5/plastic/PlasticClass.java
----------------------------------------------------------------------
diff --git a/plastic/src/main/java/org/apache/tapestry5/plastic/PlasticClass.java b/plastic/src/main/java/org/apache/tapestry5/plastic/PlasticClass.java
index e212fe5..2168456 100644
--- a/plastic/src/main/java/org/apache/tapestry5/plastic/PlasticClass.java
+++ b/plastic/src/main/java/org/apache/tapestry5/plastic/PlasticClass.java
@@ -163,6 +163,17 @@ public interface PlasticClass extends AnnotationAccess
      * @return this plastic class, for further configuration
      */
     PlasticClass proxyInterface(Class interfaceType, PlasticField field);
+    
+    /**
+     * Introduces the interface, and then invokes {@link PlasticMethod#delegateTo(PlasticMethod)}
on each method
+     * defined by the interface.
+     *
+     * @param interfaceType defines the interface to proxy
+     * @param method        method to delegate to
+     * @return this plastic class, for further configuration
+     * @since 5.4.4
+     */
+    PlasticClass proxyInterface(Class interfaceType, PlasticMethod method);
 
     /**
      * Conditionally adds an implementation of <code>toString()</code> to the
class, but only if it is not already

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/d7cc7c7d/tapestry-ioc/build.gradle
----------------------------------------------------------------------
diff --git a/tapestry-ioc/build.gradle b/tapestry-ioc/build.gradle
index 8113a23..b208818 100644
--- a/tapestry-ioc/build.gradle
+++ b/tapestry-ioc/build.gradle
@@ -15,8 +15,10 @@ dependencies {
 
     compile "org.slf4j:slf4j-api:${versions.slf4j}"
 
-    testCompile "commons-lang:commons-lang:2.6"
-
+    testCompile "org.apache.commons:commons-lang3:3.4"
+    testCompile "org.hibernate:hibernate-core:5.2.10.Final"
+    testRuntime "org.hsqldb:hsqldb:2.2.8"
+    
     provided "org.testng:testng:${versions.testng}", { transitive = false }
 }
 

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/d7cc7c7d/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/ModuleImpl.java
----------------------------------------------------------------------
diff --git a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/ModuleImpl.java
b/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/ModuleImpl.java
index 48bf24d..51f864c 100644
--- a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/ModuleImpl.java
+++ b/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/ModuleImpl.java
@@ -509,10 +509,11 @@ public class ModuleImpl implements Module
                     }
                 });
 
-                for (Method m : serviceInterface.getMethods())
-                {
-                    plasticClass.introduceMethod(m).delegateTo(delegateMethod);
-                }
+                plasticClass.proxyInterface(serviceInterface, delegateMethod);
+//                for (Method m : serviceInterface.getMethods())
+//                {
+//                    plasticClass.introduceMethod(m).delegateTo(delegateMethod);
+//                }
 
                 plasticClass.introduceMethod(WRITE_REPLACE).changeImplementation(new InstructionBuilderCallback()
                 {

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/d7cc7c7d/tapestry-ioc/src/test/groovy/ioc/specs/AspectInterceptorBuilderImplSpec.groovy
----------------------------------------------------------------------
diff --git a/tapestry-ioc/src/test/groovy/ioc/specs/AspectInterceptorBuilderImplSpec.groovy
b/tapestry-ioc/src/test/groovy/ioc/specs/AspectInterceptorBuilderImplSpec.groovy
index e543482..b614c38 100644
--- a/tapestry-ioc/src/test/groovy/ioc/specs/AspectInterceptorBuilderImplSpec.groovy
+++ b/tapestry-ioc/src/test/groovy/ioc/specs/AspectInterceptorBuilderImplSpec.groovy
@@ -1,6 +1,6 @@
 package ioc.specs
 
-import org.apache.commons.lang.StringUtils
+import org.apache.commons.lang3.StringUtils
 import org.apache.tapestry5.ioc.internal.services.TextTransformer
 import org.apache.tapestry5.ioc.services.AspectDecorator
 import org.apache.tapestry5.plastic.MethodAdvice

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/d7cc7c7d/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/AdviceModule.java
----------------------------------------------------------------------
diff --git a/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/AdviceModule.java
b/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/AdviceModule.java
index 0e0a186..f943152 100644
--- a/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/AdviceModule.java
+++ b/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/AdviceModule.java
@@ -13,9 +13,15 @@
 // limitations under the License.
 package org.apache.tapestry5.ioc.internal;
 
+
 import org.apache.tapestry5.ioc.MethodAdviceReceiver;
+import org.apache.tapestry5.ioc.ObjectLocator;
+import org.apache.tapestry5.ioc.Registry;
+import org.apache.tapestry5.ioc.RegistryBuilder;
 import org.apache.tapestry5.ioc.ServiceBinder;
 import org.apache.tapestry5.ioc.annotations.Advise;
+import org.hibernate.Session;
+import org.hibernate.cfg.Configuration;
 
 public class AdviceModule
 {
@@ -45,4 +51,19 @@ public class AdviceModule
             final MethodAdviceReceiver methodAdviceReceiver) {
         methodAdviceReceiver.adviseAllMethods(new TestAdvice());
     }
+    
+//    public static void main(String[] args) {
+//	Registry registry = RegistryBuilder.buildAndStartupRegistry(AdviceModule.class);
+//	Session session = registry.getService(Session.class);
+//    }
+    
+    // TAP5-2582
+    public static Session buildHibernateSession(
+	    ObjectLocator objectLocator
+	) {
+	    return new Configuration()
+	        .configure("hibernate.cfg.xml")
+	        .buildSessionFactory()
+	        .openSession();
+	}
 }


Mime
View raw message