Uploaded image for project: 'Camel'
  1. Camel
  2. CAMEL-9690

bean parameter binding should check parameter types when using simple expressions

    XMLWordPrintableJSON

Details

    • Improvement
    • Status: Resolved
    • Minor
    • Resolution: Fixed
    • 2.16.2
    • 2.18.0
    • camel-core
    • None
    • mac

    • Unknown

    Description

      Hello

      I’m using camel 2.16.2 and I’m finding the bean parameter binding doesn’t seem to work very well on overloaded methods. See below for an example

      public class ClassA {
      	public int foo() {
      		return 0;
      	}
      
      	public int foo(String param1) {
      		return 1;
      	}
      
      	public int foo(String param1, String param2) {
      		return 2;
      	}
      
      	public int foo(String param1, ClassB param2) {
      		return 3;
      	}
      
      	public int foo(boolean param1, String param2) {
      		return 4;
      	}
      }
      
      public class ClassB {
      
      }
      

      Here are the routes

      from("direct:noParam").bean(ClassA.class, "foo()").to("mock:end");
      from("direct:1Param").bean(ClassA.class, "foo(${body})").to("mock:end");
      from("direct:2Param").bean(ClassA.class, "foo(${body}, ${header.key})").to("mock:end”);
      

      And here are the tests

      	@EndpointInject(uri = "mock:end")
      	private MockEndpoint end;
      
      	@Produce
      	private ProducerTemplate producerTemplate;
      
      	@Test
      	// passes
      	public void testNoParam() throws InterruptedException {
      		end.expectedBodiesReceived(0);
      		producerTemplate.sendBodyAndHeader("direct:noParam", "body", "key", "value");
      		end.assertIsSatisfied();
      	}
      
      	@Test
      	// passes
      	public void test1Param() throws InterruptedException {
      		end.expectedBodiesReceived(1);
      		producerTemplate.sendBodyAndHeader("direct:1Param", "body", "key", "value");
      		end.assertIsSatisfied();
      	}
      
      	@Test
      	// throws ambiguous method call exception
      	public void test2Param_string() throws InterruptedException {
      		end.expectedBodiesReceived(2);
      		producerTemplate.sendBodyAndHeader("direct:2Param", "body", "key", "value");
      		end.assertIsSatisfied();
      	}
      
      	@Test
      	// throws ambiguous method call exception
      	public void test2Param_classB() throws InterruptedException {
      		end.expectedBodiesReceived(3);
      		producerTemplate.sendBodyAndHeader("direct:2Param", "body", "key", new ClassB());
      		end.assertIsSatisfied();
      	}
      
      	@Test
      	// passes
      	public void test2Param_boolBody() throws InterruptedException {
      		end.expectedBodiesReceived(4);
      		producerTemplate.sendBodyAndHeader("direct:2Param", true, "key", "value");
      		end.assertIsSatisfied();
      	}
      

      I don’t understand why test2Param_string and test2Param_classB throw ambiguous call exceptions. Here’s a sample stack trace.

      org.apache.camel.component.bean.AmbiguousMethodCallException: Ambiguous method invocations possible: [public int au.com.winning.navmidware.routes.navws.ClassA.foo(java.lang.String,java.lang.String), public int au.com.winning.navmidware.routes.navws.ClassA.foo(java.lang.String,au.com.winning.navmidware.routes.navws.ClassB)]. Exchange[ID-minhmac-local-53614-1457474273519-0-2][Message: body]
      	at org.apache.camel.component.bean.BeanInfo.chooseBestPossibleMethodInfo(BeanInfo.java:835) ~[camel-core-2.16.2.jar:2.16.2]
      	at org.apache.camel.component.bean.BeanInfo.chooseMethodWithMatchingBody(BeanInfo.java:764) ~[camel-core-2.16.2.jar:2.16.2]
      	at org.apache.camel.component.bean.BeanInfo.chooseMethod(BeanInfo.java:621) ~[camel-core-2.16.2.jar:2.16.2]
      	at org.apache.camel.component.bean.BeanInfo.createInvocation(BeanInfo.java:254) ~[camel-core-2.16.2.jar:2.16.2]
      	at org.apache.camel.component.bean.BeanInfo.createInvocation(BeanInfo.java:183) ~[camel-core-2.16.2.jar:2.16.2]
      

      From looking at the code in BeanInfo, I think it just tries to match the type on the body and if it sees multiple possible methods then it throws the exception. I believe it should go further and try to match the type on the other parameters as well?

      To get around this issue temporarily, I’ve had to write an adapter class that wraps around ClassA but it’s not an ideal solution.

      Attachments

        Issue Links

          Activity

            People

              davsclaus Claus Ibsen
              mtran Minh Tran
              Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved: