You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2012/09/28 15:53:07 UTC

svn commit: r1391466 - in /camel/trunk/camel-core/src: main/java/org/apache/camel/component/bean/ test/java/org/apache/camel/builder/

Author: davsclaus
Date: Fri Sep 28 13:53:06 2012
New Revision: 1391466

URL: http://svn.apache.org/viewvc?rev=1391466&view=rev
Log:
CAMEL-5571: Camel proxy should not forward methods from java.lang.Object

Added:
    camel/trunk/camel-core/src/test/java/org/apache/camel/builder/ProxyBuilderSkipJavaLangObjectMethodsTest.java
      - copied, changed from r1391441, camel/trunk/camel-core/src/test/java/org/apache/camel/builder/ProxyBuilderTest.java
Modified:
    camel/trunk/camel-core/src/main/java/org/apache/camel/component/bean/AbstractCamelInvocationHandler.java
    camel/trunk/camel-core/src/main/java/org/apache/camel/component/bean/CamelInvocationHandler.java
    camel/trunk/camel-core/src/main/java/org/apache/camel/component/bean/PojoMessageInvocationHandler.java

Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/component/bean/AbstractCamelInvocationHandler.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/component/bean/AbstractCamelInvocationHandler.java?rev=1391466&r1=1391465&r2=1391466&view=diff
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/component/bean/AbstractCamelInvocationHandler.java (original)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/component/bean/AbstractCamelInvocationHandler.java Fri Sep 28 13:53:06 2012
@@ -19,6 +19,9 @@ package org.apache.camel.component.bean;
 import java.lang.reflect.InvocationHandler;
 import java.lang.reflect.Method;
 import java.lang.reflect.Type;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
 import java.util.concurrent.Callable;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.ExecutorService;
@@ -41,10 +44,16 @@ import org.slf4j.LoggerFactory;
 public abstract class AbstractCamelInvocationHandler implements InvocationHandler {
 
     private static final transient Logger LOG = LoggerFactory.getLogger(CamelInvocationHandler.class);
+    private static final List<Method> EXCLUDED_METHODS = new ArrayList<Method>();
     private static ExecutorService executorService;
     protected final Endpoint endpoint;
     protected final Producer producer;
 
+    static {
+        // exclude all java.lang.Object methods as we dont want to invoke them
+        EXCLUDED_METHODS.addAll(Arrays.asList(Object.class.getMethods()));
+    }
+
     public AbstractCamelInvocationHandler(Endpoint endpoint, Producer producer) {
         this.endpoint = endpoint;
         this.producer = producer;
@@ -67,7 +76,26 @@ public abstract class AbstractCamelInvoc
         }
     }
 
-    protected Object invokeWithbody(final Method method, Object body, final ExchangePattern pattern) throws InterruptedException, Throwable {
+    @Override
+    public final Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable {
+        if (isValidMethod(method)) {
+            return doInvokeProxy(proxy, method, args);
+        } else {
+            // invalid method then invoke methods on this instead
+            if ("toString".equals(method.getName())) {
+                return this.toString();
+            } else if ("hashCode".equals(method.getName())) {
+                return this.hashCode();
+            } else if ("equals".equals(method.getName())) {
+                return Boolean.FALSE;
+            }
+            return null;
+        }
+    }
+
+    public abstract Object doInvokeProxy(final Object proxy, final Method method, final Object[] args) throws Throwable;
+
+    protected Object invokeWithBody(final Method method, Object body, final ExchangePattern pattern) throws Throwable {
         final Exchange exchange = new DefaultExchange(endpoint, pattern);
         exchange.getIn().setBody(body);
 
@@ -214,4 +242,15 @@ public abstract class AbstractCamelInvoc
         return null;
     }
 
+    protected boolean isValidMethod(Method method) {
+        // must not be in the excluded list
+        for (Method excluded : EXCLUDED_METHODS) {
+            if (ObjectHelper.isOverridingMethod(excluded, method)) {
+                // the method is overriding an excluded method so its not valid
+                return false;
+            }
+        }
+        return true;
+    }
+
 }

Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/component/bean/CamelInvocationHandler.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/component/bean/CamelInvocationHandler.java?rev=1391466&r1=1391465&r2=1391466&view=diff
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/component/bean/CamelInvocationHandler.java (original)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/component/bean/CamelInvocationHandler.java Fri Sep 28 13:53:06 2012
@@ -37,11 +37,12 @@ public class CamelInvocationHandler exte
         this.methodInfoCache = methodInfoCache;
     }
 
-    public Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable {
+    @Override
+    public Object doInvokeProxy(Object proxy, Method method, Object[] args) throws Throwable {
         BeanInvocation invocation = new BeanInvocation(method, args);
         MethodInfo methodInfo = methodInfoCache.getMethodInfo(method);
         final ExchangePattern pattern = methodInfo != null ? methodInfo.getPattern() : ExchangePattern.InOut;
-        return invokeWithbody(method, invocation, pattern);
+        return invokeWithBody(method, invocation, pattern);
     }
 
 }

Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/component/bean/PojoMessageInvocationHandler.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/component/bean/PojoMessageInvocationHandler.java?rev=1391466&r1=1391465&r2=1391466&view=diff
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/component/bean/PojoMessageInvocationHandler.java (original)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/component/bean/PojoMessageInvocationHandler.java Fri Sep 28 13:53:06 2012
@@ -24,17 +24,19 @@ import org.apache.camel.Producer;
 import org.apache.camel.RuntimeCamelException;
 
 /**
- * Special InvocationHandler for methods that have only one parameter. This
+ * Special {@link java.lang.reflect.InvocationHandler} for methods that have only one parameter. This
  * parameter is directly sent to as the body of the message. The idea is to use
  * that as a very open message format especially when combined with e.g. JAXB
  * serialization.
  */
 public class PojoMessageInvocationHandler extends AbstractCamelInvocationHandler {
+
     public PojoMessageInvocationHandler(Endpoint endpoint, Producer producer) {
         super(endpoint, producer);
     }
 
-    public Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable {
+    @Override
+    public Object doInvokeProxy(Object proxy, Method method, Object[] args) throws Throwable {
         int argsLength = (args == null) ? 0 : args.length;
         if (argsLength != 1) {
             throw new RuntimeCamelException(String.format("Error creating proxy for %s.%s Number of arguments must be 1 but is %d", 
@@ -42,7 +44,7 @@ public class PojoMessageInvocationHandle
                                                           method.getName(), argsLength));
         }
         final ExchangePattern pattern = method.getReturnType() != Void.TYPE ? ExchangePattern.InOut : ExchangePattern.InOnly;
-        return invokeWithbody(method, args[0], pattern);
+        return invokeWithBody(method, args[0], pattern);
     }
 
 }

Copied: camel/trunk/camel-core/src/test/java/org/apache/camel/builder/ProxyBuilderSkipJavaLangObjectMethodsTest.java (from r1391441, camel/trunk/camel-core/src/test/java/org/apache/camel/builder/ProxyBuilderTest.java)
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/builder/ProxyBuilderSkipJavaLangObjectMethodsTest.java?p2=camel/trunk/camel-core/src/test/java/org/apache/camel/builder/ProxyBuilderSkipJavaLangObjectMethodsTest.java&p1=camel/trunk/camel-core/src/test/java/org/apache/camel/builder/ProxyBuilderTest.java&r1=1391441&r2=1391466&rev=1391466&view=diff
==============================================================================
--- camel/trunk/camel-core/src/test/java/org/apache/camel/builder/ProxyBuilderTest.java (original)
+++ camel/trunk/camel-core/src/test/java/org/apache/camel/builder/ProxyBuilderSkipJavaLangObjectMethodsTest.java Fri Sep 28 13:53:06 2012
@@ -16,24 +16,27 @@
  */
 package org.apache.camel.builder;
 
-import java.util.concurrent.Future;
-import java.util.concurrent.TimeUnit;
-
 import org.apache.camel.ContextTestSupport;
 
 /**
  *
  */
-public class ProxyBuilderTest extends ContextTestSupport {
+public class ProxyBuilderSkipJavaLangObjectMethodsTest extends ContextTestSupport {
 
     public void testSayFoo() throws Exception {
+        getMockEndpoint("mock:start").expectedBodiesReceived("Camel");
+
         Foo foo = new ProxyBuilder(context).endpoint("direct:start").build(Foo.class);
 
-        Future<String> future = foo.sayHello("Camel");
-        assertNotNull(future);
-        assertFalse("Should not be done", future.isDone());
+        String out = foo.sayHello("Camel");
+        assertEquals("Hello Camel", out);
+
+        // these methods should not be proxied as they are from java.lang.Object
+        assertNotNull(foo.hashCode());
+        assertNotNull(foo.toString());
+        assertFalse(foo.equals(null));
 
-        assertEquals("Hello Camel", future.get(5, TimeUnit.SECONDS));
+        assertMockEndpointsSatisfied();
     }
 
     @Override
@@ -42,13 +45,13 @@ public class ProxyBuilderTest extends Co
             @Override
             public void configure() throws Exception {
                 from("direct:start")
-                    .delay(1000)
+                    .to("mock:start")
                     .transform(body().prepend("Hello "));
             }
         };
     }
 
     interface Foo {
-        Future<String> sayHello(String body);
+        String sayHello(String body);
     }
 }