camel-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From James Strachan <james.strac...@gmail.com>
Subject Re: How to avoid a org.apache.camel.component.bean.AmbiguousMethodCallException when calling methods of a Bean component
Date Tue, 14 Jul 2009 11:03:54 GMT
If you want camel to be able to pick the right method based on the
payloads when there are multiple methods with the same name; then the
methods must use a concrete type for the payload (and you must send a
message with that payload).

The method signatures are kinda vague...
   @Handler
   public void updateRequestStatus(
           @Header(value = "messageType") String messageType,
           @Header(value = "requestStatus") String requestStatus,
           @Header(value = "requestId") String requestId,
           Exchange exchange) {

   @Handler
   public List<RequestMessage> updateRequestStatus(
           @Header(value = "messageType") String messageType,
           @Header(value = "requestId") String requestId,
           @Body List<RequestMessage> requestMessages) {

the first method will match pretty much all message exchanges, the
second (due to type erasure in Java generics) will match any List
payload. Hence any message with a payload that can be converted to a
List will cause ambiguity.

Why not just use different named methods and invoke the right method
from the right bit of the route? Or use a Content Based Router first
to pick the right method?


The intent BTW of letting camel choose the right method is when you
are using DTOs for the payload of the message. e.g.

public Whatever doSomething(PurchaseOrder body, ...) {...}
public Whatever doAnotherThing(Invoice body, ...) {...}


2009/7/14 Charles Moulliard <cmoulliard@gmail.com>:
> I create a virtual route to explain my purpose but indeed the error is not
> at all related to what I copy.
>
>  Here is the route corresponding to what I have
>
> *Scenario 1 : @Hanlder added to both methods*
>
>        <!--
>            Core component Flow IN to OUT Process P3 technical parsing
>        -->
>        <camel:route errorHandlerRef="txErrorHandler">
>            <camel:from ref="queueRequestEndpoint" />
>            <camel:transacted ref="PROPAGATION_REQUIRED" />
>
>            <camel:doTry>
>
>                <camel:convertBodyTo
> type="com.xpectis.x3s.platform.model.Request" />
>
>                <!-- Parse the request -->
>                <camel:bean ref="serviceHelper" method="parseRequest" />
>
>                <!-- Update request status -->
> *                <camel:bean ref="serviceHelper"
> method="updateRequestStatus"/>*
>
>                <!-- Put request in the queue -->
>                <camel:to ref="directRequestMessageEndpoint" />
>
>                <camel:doCatch>
>
> <camel:exception>com.xpectis.x3s.exception.X3SClientException</camel:exception>
>                    <camel:bean ref="serviceHelper"
> method="processException" />
>                    <camel:to ref="queueReportingEndpoint" />
>                </camel:doCatch>
>
>                <camel:doCatch>
>                    <camel:exception>java.lang.Exception</camel:exception>
>                    <camel:to
> uri="log:x3slog?level=DEBUG&amp;multiline=true" />
>                    <camel:rollback/>
>                </camel:doCatch>
>
>            </camel:doTry>
>
>        </camel:route>
>
>        <!--
>            Core component Flow IN to OUT Process P3 request message
> creation
>        -->
>        <camel:route errorHandlerRef="txErrorHandler">
>            <camel:from ref="directRequestMessageEndpoint" />
>            <camel:transacted ref="PROPAGATION_REQUIRED" />
>            <camel:doTry>
>
>            <!-- Split the collection of messages -->
>            <camel:split strategyRef="aggregationStrat">
>                <camel:ognl>request.body</camel:ognl>
>
>                <!-- (1) Call the service to save the request message -->
>                <camel:bean ref="serviceHelper"
> method="createRequestMessage" />
>
>                <!-- (2) Validate the business message -->
>                <camel:bean ref="serviceHelper"
> method="validateRequestMessage" />
>
>                <!-- (3) Save business message -->
>                <camel:bean ref="serviceHelper" method="saveRequestMessage"
> />
>
>            </camel:split>
>
>            <!-- Update Request status -->
> *            <camel:bean ref="serviceHelper" method="updateRequestStatus" />
> *
>
>            <!-- <camel:bean ref="serviceHelper" method="generateError" />
> -->
>
>            <!-- Put result in queue -->
>            <camel:to ref="queueRequestMessageEndpoint" />
>
>            <camel:doCatch>
>                    <camel:exception>java.lang.Exception</camel:exception>
>                    <camel:to
> uri="log:x3slog?level=DEBUG&amp;multiline=true" />
>                    <camel:rollback/>
>            </camel:doCatch>
>            </camel:doTry>
>
>        </camel:route>
>
> and the methods :
>
>    @Handler
>    public void updateRequestStatus(
>            @Header(value = "messageType") String messageType,
>            @Header(value = "requestStatus") String requestStatus,
>            @Header(value = "requestId") String requestId,
>            Exchange exchange) {
>
>    @Handler
>    public List<RequestMessage> updateRequestStatus(
>            @Header(value = "messageType") String messageType,
>            @Header(value = "requestId") String requestId,
>            @Body List<RequestMessage> requestMessages) {
>
>
>
> error :
>
> Exception: org.apache.camel.component.bean.AmbiguousMethodCallException:
> Ambiguous method invocations possible: [public java.util.List
> com.xpectis.x3s.core.util.ServiceHelper.updateRequestStatus(java.lang.String,java.lang.String,java.util.List),
> public void
> com.xpectis.x3s.core.util.ServiceHelper.updateRequestStatus(java.lang.String,java.lang.String,java.lang.String,org.apache.camel.Exchange)]
>
>
> *Scenario 2 : @Hanlder added to method with void
>
> *In this case, I don't have any error returned Exception:
> org.apache.camel.component.bean.AmbiguousMethodCallException BUT the method
> without the @Handler annotation is executed and not the other.*
>
> *
> Regards,
>
> Charles Moulliard
> Senior Enterprise Architect
> Apache Camel Committer
>
> *****************************
> blog : http://cmoulliard.blogspot.com
>
>
> On Tue, Jul 14, 2009 at 12:00 PM, James Strachan
> <james.strachan@gmail.com>wrote:
>
>> 2009/7/14 Charles Moulliard <cmoulliard@gmail.com>:
>> > If I annotate one of them : the one annotated is executed but the other
>> is
>> > missed in the route
>> >
>> > Is this syntax correct :
>> >
>> > from(file)
>> > .to(beanA) // Create Request
>> > .to(beanB) // parse request
>> > .to(queueA)
>> >
>> > from(queueA)
>> > .to(beanC) // validate request
>> > .to(beanD method="updateStatus")
>> > .to(queueB)
>> >
>> > ...
>> >
>> > from(queueX)
>> > .to(beanX)
>> > .to(beanD method="updateStatus")
>> >
>> > public class beanD {
>> >
>> >    @Handler
>> >    public void updateStatus(@Body Request request) {
>> >
>> >    }
>> >
>> >    public void updateStatus(@Body Report report, @Header(
>> value="requestId"
>> > ) String requestId) {
>> >
>> >    }
>> > }
>>
>> This thread is feeling a bit like the goal posts keep moving.
>>
>> With the above, if the payload of the message is a Request or Report
>> then camel should pick the right one.
>>
>> However your exception showed no such thing...
>>
>>
>> Exception: org.apache.camel.component.bean.AmbiguousMethodCallException:
>> Ambiguous method invocations possible: [public java.util.List
>>
>> com.xpectis.x3s.core.util.ServiceHelper.updateRequestStatus(java.lang.String,java.lang.String,java.util.List),
>> public void
>>
>> com.xpectis.x3s.core.util.ServiceHelper.updateRequestStatus(java.lang.String,java.lang.String,java.lang.String,org.apache.camel.Exchange)]
>>
>>
>>
>> What was the exception when you tried to use the 2 methods in this
>> latest message - and what was the type of the payload?
>>
>> --
>> James
>> -------
>> http://macstrac.blogspot.com/
>>
>> Open Source Integration
>> http://fusesource.com/
>>
>



-- 
James
-------
http://macstrac.blogspot.com/

Open Source Integration
http://fusesource.com/

Mime
View raw message