Repository: camel Updated Branches: refs/heads/camel-2.16.x 7578430a5 -> 0dc9ee6e0 refs/heads/camel-2.17.x af76cd219 -> 36f39ccca refs/heads/master 9c5f002ac -> 5639b7860
CAMEL-9656: Bean component fixed to detect duplicate methods from generic bridge methods. Project: http://git-wip-us.apache.org/repos/asf/camel/repo Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/5639b786 Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/5639b786 Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/5639b786 Branch: refs/heads/master Commit: 5639b7860037f8ad387bfaa49a7a2b5e61d0d0e3 Parents: 9c5f002 Author: Claus Ibsen <davscl...@apache.org> Authored: Tue Mar 22 10:08:52 2016 +0100 Committer: Claus Ibsen <davscl...@apache.org> Committed: Tue Mar 22 10:46:24 2016 +0100 ---------------------------------------------------------------------- .../apache/camel/component/bean/BeanInfo.java | 24 +++++++------------ .../org/apache/camel/util/ObjectHelper.java | 14 +++++++++-- .../issues/BeanInfoSingleMethodServiceTest.java | 15 +++++++++--- .../issues/SingleMethodAbstractService.java | 25 ++++++++++++++++++++ .../bean/issues/SingleMethodServiceImpl.java | 2 +- .../example/spring/boot/MySpringBootRouter.java | 9 +++++++ .../spring/boot/MySpringBootRouterTest.java | 4 ++-- 7 files changed, 69 insertions(+), 24 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/camel/blob/5639b786/camel-core/src/main/java/org/apache/camel/component/bean/BeanInfo.java ---------------------------------------------------------------------- diff --git a/camel-core/src/main/java/org/apache/camel/component/bean/BeanInfo.java b/camel-core/src/main/java/org/apache/camel/component/bean/BeanInfo.java index 4409086..ed065a6 100644 --- a/camel-core/src/main/java/org/apache/camel/component/bean/BeanInfo.java +++ b/camel-core/src/main/java/org/apache/camel/component/bean/BeanInfo.java @@ -191,9 +191,7 @@ public class BeanInfo { // find the explicit method to invoke if (explicitMethod != null) { - Iterator<List<MethodInfo>> it = operations.values().iterator(); - while (it.hasNext()) { - List<MethodInfo> infos = it.next(); + for (List<MethodInfo> infos : operations.values()) { for (MethodInfo info : infos) { if (explicitMethod.equals(info.getMethod())) { return info.createMethodInvocation(pojo, exchange); @@ -244,7 +242,7 @@ public class BeanInfo { // only one method then choose it methodInfo = methods.get(0); - // validate that if we want an explict no-arg method, then that's what we get + // validate that if we want an explicit no-arg method, then that's what we get if (emptyParameters && methodInfo.hasParameters()) { throw new MethodNotFoundException(exchange, pojo, methodName, "(with no parameters)"); } @@ -263,7 +261,7 @@ public class BeanInfo { } } - if (methodInfo == null || !name.equals(methodInfo.getMethod().getName())) { + if (methodInfo == null || (name != null && !name.equals(methodInfo.getMethod().getName()))) { throw new AmbiguousMethodCallException(exchange, methods); } } else { @@ -318,18 +316,13 @@ public class BeanInfo { } Set<Method> overrides = new HashSet<Method>(); + Set<Method> bridges = new HashSet<Method>(); // do not remove duplicates form class from the Java itself as they have some "duplicates" we need boolean javaClass = clazz.getName().startsWith("java.") || clazz.getName().startsWith("javax."); if (!javaClass) { // it may have duplicate methods already, even from declared or from interfaces + declared for (Method source : methods) { - - // skip bridge methods in duplicate checks (as the bridge method is inserted by the compiler due to type erasure) - if (source.isBridge()) { - continue; - } - for (Method target : methods) { // skip ourselves if (ObjectHelper.isOverridingMethod(source, target, true)) { @@ -400,9 +393,9 @@ public class BeanInfo { LOG.trace("Adding operation: {} for method: {}", opName, methodInfo); - if (hasMethod(opName)) { + List<MethodInfo> existing = getOperations(opName); + if (existing != null) { // we have an overloaded method so add the method info to the same key - List<MethodInfo> existing = getOperations(opName); existing.add(methodInfo); } else { // its a new method we have not seen before so wrap it in a list and add it @@ -429,7 +422,6 @@ public class BeanInfo { return methodInfo; } - /** * Returns the {@link MethodInfo} for the given method if it exists or null * if there is no metadata available for the given method @@ -1040,7 +1032,7 @@ public class BeanInfo { } // must match name - if (!name.equals(method.getName())) { + if (name != null && !name.equals(method.getName())) { return false; } @@ -1203,7 +1195,7 @@ public class BeanInfo { if (IntrospectionSupport.isGetter(method)) { String shorthandMethodName = IntrospectionSupport.getGetterShorthandName(method); // if the two names matches then see if we can find it using that name - if (methodName.equals(shorthandMethodName)) { + if (methodName != null && methodName.equals(shorthandMethodName)) { return operations.get(method.getName()); } } http://git-wip-us.apache.org/repos/asf/camel/blob/5639b786/camel-core/src/main/java/org/apache/camel/util/ObjectHelper.java ---------------------------------------------------------------------- diff --git a/camel-core/src/main/java/org/apache/camel/util/ObjectHelper.java b/camel-core/src/main/java/org/apache/camel/util/ObjectHelper.java index 65372f0..1a18a4b 100644 --- a/camel-core/src/main/java/org/apache/camel/util/ObjectHelper.java +++ b/camel-core/src/main/java/org/apache/camel/util/ObjectHelper.java @@ -1320,7 +1320,12 @@ public final class ObjectHelper { } } else { if (!source.getReturnType().isAssignableFrom(target.getReturnType())) { - return false; + boolean b1 = source.isBridge(); + boolean b2 = target.isBridge(); + // must not be bridge methods + if (!b1 && !b2) { + return false; + } } } @@ -1337,7 +1342,12 @@ public final class ObjectHelper { } } else { if (!(source.getParameterTypes()[i].isAssignableFrom(target.getParameterTypes()[i]))) { - return false; + boolean b1 = source.isBridge(); + boolean b2 = target.isBridge(); + // must not be bridge methods + if (!b1 && !b2) { + return false; + } } } } http://git-wip-us.apache.org/repos/asf/camel/blob/5639b786/camel-core/src/test/java/org/apache/camel/component/bean/issues/BeanInfoSingleMethodServiceTest.java ---------------------------------------------------------------------- diff --git a/camel-core/src/test/java/org/apache/camel/component/bean/issues/BeanInfoSingleMethodServiceTest.java b/camel-core/src/test/java/org/apache/camel/component/bean/issues/BeanInfoSingleMethodServiceTest.java index 6121720..51f43ba 100644 --- a/camel-core/src/test/java/org/apache/camel/component/bean/issues/BeanInfoSingleMethodServiceTest.java +++ b/camel-core/src/test/java/org/apache/camel/component/bean/issues/BeanInfoSingleMethodServiceTest.java @@ -16,6 +16,8 @@ */ package org.apache.camel.component.bean.issues; +import java.lang.reflect.Method; + import org.apache.camel.ContextTestSupport; import org.apache.camel.builder.RouteBuilder; import org.apache.camel.component.bean.BeanInfo; @@ -34,12 +36,19 @@ public class BeanInfoSingleMethodServiceTest extends ContextTestSupport { public void testBeanInfoSingleMethod() throws Exception { BeanInfo beaninfo = new BeanInfo(context, SingleMethodService.class); - assertEquals("Should find the single method", 1, beaninfo.getMethods().size()); + assertEquals(1, beaninfo.getMethods().size()); + assertEquals("doSomething", beaninfo.getMethods().get(0).getMethod().getName()); } public void testBeanInfoSingleMethodImpl() throws Exception { BeanInfo beaninfo = new BeanInfo(context, SingleMethodServiceImpl.class); - assertEquals("Should find the single method", 1, beaninfo.getMethods().size()); + assertEquals(2, beaninfo.getMethods().size()); + assertEquals("doSomething", beaninfo.getMethods().get(0).getMethod().getName()); + assertEquals("hello", beaninfo.getMethods().get(1).getMethod().getName()); + + Method method = beaninfo.getMethods().get(0).getMethod(); + Object out = method.invoke(myService, "Bye World"); + assertEquals("You said Bye World", out); } @Override @@ -48,7 +57,7 @@ public class BeanInfoSingleMethodServiceTest extends ContextTestSupport { @Override public void configure() throws Exception { from("direct:start") - .bean(myService) + .bean(myService, "doSomething") .to("mock:result"); } }; http://git-wip-us.apache.org/repos/asf/camel/blob/5639b786/camel-core/src/test/java/org/apache/camel/component/bean/issues/SingleMethodAbstractService.java ---------------------------------------------------------------------- diff --git a/camel-core/src/test/java/org/apache/camel/component/bean/issues/SingleMethodAbstractService.java b/camel-core/src/test/java/org/apache/camel/component/bean/issues/SingleMethodAbstractService.java new file mode 100644 index 0000000..8c42626 --- /dev/null +++ b/camel-core/src/test/java/org/apache/camel/component/bean/issues/SingleMethodAbstractService.java @@ -0,0 +1,25 @@ +/** + * 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.apache.camel.component.bean.issues; + +public abstract class SingleMethodAbstractService<S, T> implements SingleMethodService<S, T> { + + public String hello() { + return "Hello World"; + } + +} http://git-wip-us.apache.org/repos/asf/camel/blob/5639b786/camel-core/src/test/java/org/apache/camel/component/bean/issues/SingleMethodServiceImpl.java ---------------------------------------------------------------------- diff --git a/camel-core/src/test/java/org/apache/camel/component/bean/issues/SingleMethodServiceImpl.java b/camel-core/src/test/java/org/apache/camel/component/bean/issues/SingleMethodServiceImpl.java index c477669..864b4b1 100644 --- a/camel-core/src/test/java/org/apache/camel/component/bean/issues/SingleMethodServiceImpl.java +++ b/camel-core/src/test/java/org/apache/camel/component/bean/issues/SingleMethodServiceImpl.java @@ -16,7 +16,7 @@ */ package org.apache.camel.component.bean.issues; -public class SingleMethodServiceImpl implements SingleMethodService<String, String> { +public class SingleMethodServiceImpl extends SingleMethodAbstractService<String, String> { @Override public String doSomething(String foo) { http://git-wip-us.apache.org/repos/asf/camel/blob/5639b786/examples/camel-example-spring-boot/src/main/java/org/apache/camel/example/spring/boot/MySpringBootRouter.java ---------------------------------------------------------------------- diff --git a/examples/camel-example-spring-boot/src/main/java/org/apache/camel/example/spring/boot/MySpringBootRouter.java b/examples/camel-example-spring-boot/src/main/java/org/apache/camel/example/spring/boot/MySpringBootRouter.java index c429d65..a581c07 100644 --- a/examples/camel-example-spring-boot/src/main/java/org/apache/camel/example/spring/boot/MySpringBootRouter.java +++ b/examples/camel-example-spring-boot/src/main/java/org/apache/camel/example/spring/boot/MySpringBootRouter.java @@ -17,17 +17,26 @@ package org.apache.camel.example.spring.boot; import org.apache.camel.spring.boot.FatJarRouter; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.actuate.endpoint.HealthEndpoint; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.Bean; @SpringBootApplication public class MySpringBootRouter extends FatJarRouter { + @Autowired + private HealthEndpoint health; + @Override public void configure() { from("timer:trigger") .transform().simple("ref:myBean") .to("log:out"); + + from("timer:status") + .bean(health, "invoke") + .log("Health is ${body}"); } @Bean http://git-wip-us.apache.org/repos/asf/camel/blob/5639b786/examples/camel-example-spring-boot/src/test/java/org/apache/camel/example/spring/boot/MySpringBootRouterTest.java ---------------------------------------------------------------------- diff --git a/examples/camel-example-spring-boot/src/test/java/org/apache/camel/example/spring/boot/MySpringBootRouterTest.java b/examples/camel-example-spring-boot/src/test/java/org/apache/camel/example/spring/boot/MySpringBootRouterTest.java index 91fc2aa..1fe34f6 100644 --- a/examples/camel-example-spring-boot/src/test/java/org/apache/camel/example/spring/boot/MySpringBootRouterTest.java +++ b/examples/camel-example-spring-boot/src/test/java/org/apache/camel/example/spring/boot/MySpringBootRouterTest.java @@ -38,9 +38,9 @@ public class MySpringBootRouterTest extends Assert { @Test public void shouldProduceMessages() throws InterruptedException { - // we expect that one or more messages is automatic done by the Camel + // we expect that a number of messages is automatic done by the Camel // route as it uses a timer to trigger - NotifyBuilder notify = new NotifyBuilder(camelContext).whenDone(1).create(); + NotifyBuilder notify = new NotifyBuilder(camelContext).whenDone(4).create(); assertTrue(notify.matches(10, TimeUnit.SECONDS)); }