Results 1 to 5 of 5

Thread: Exception: Found ambiguous parameter type

  1. #1

    Default Exception: Found ambiguous parameter type

    I've found that I need to have two gateways. The first represents the non-messaging contract, the second, the messaging contract. I'm generating service activators to handle asynchronous returns, errors, timeouts, nulls, etc, as shown here.

    My configuration is like this:

    HTML Code:
        <bean id="cartridgeServiceAggregator" class="payload.CartridgeServiceAggregator"/>
    
        <int:gateway id="cartridgeServiceGateway" service-interface="ICartridgeServiceGateway"
                     default-request-channel="cartridgeservice-request-channel-gateway"
                     default-reply-channel="cartridgeservice-reply-channel">
            <int:method name="getBarCodeTemplates" payload-expression="@cartridgeServiceParms.aggregateGetBarCodeTemplates( )"/>
            <int:method name="addBarCodeTemplate" payload-expression="@cartridgeServiceParms.aggregateAddBarCodeTemplate( #args[0], #args[1], #args[2], #args[3] )"/>
            <int:method name="deleteBarCodeTemplate" payload-    
            <int:method name="getCartridges" payload-expression="@cartridgeServiceParms.aggregateGetCartridges( #args[0], #args[1], #args[2], #args[3] )"/>
        </int:gateway>
    
        <int:service-activator id="cartridgeservice-request-channel-activator" input-channel="cartridgeservice-request-channel-gateway">
            <bean class="com.sepaton.vtl.api.gateway.core.contracts.activators.CartridgeServiceServiceActivator">
                <constructor-arg name="messagingGateway" ref="cartridgeServiceGateway-async"/>
            </bean>
        </int:service-activator>
    
        <int:channel id="cartridgeservice-request-channel-msg-gateway">
            <int:dispatcher task-executor="vtlEsbExecutor"/>
        </int:channel>
    
        <int:gateway id="cartridgeServiceGateway-async"
                         service-interface="ICartridgeServiceMessagingGateway"
                         default-request-channel="cartridgeservice-request-channel-msg-gateway"
                         default-reply-timeout="6000"/>
    The first gateway aggregates all parameters into a single java object. That object is serializable via JaxB. All my methods take the same object, but all variables are set to null unless set by payload expression.

    The activator implements all the methods like this:

    Code:
        public ResultObject<CartridgeResults> getCartridges(CartridgeServiceParms message) {
            //throws InterruptedException, ExecutionException, TimeoutException
            try {
                Future<ResultObject<CartridgeResults>> futureResponse = messagingGateway.getCartridges(message);
                return futureResponse.get(15, TimeUnit.SECONDS);
            } catch (Exception e) {
                // Eat it for now
                return null;
            }
        }
    The original gateway had a bunch of parameters, this activator accepts a signature that is just the aggregated payload object. This isn't done as you can see. But it should get called.

    The messaging interface looks just like the original gateway interface, except that it wraps returns as Future, and has the aggregate object for a parameter. For the method shown above, it looks like this:

    Original gateway interface:
    Code:
        ResultObject<CartridgeResults> getCartridges(String barcodePrefix,
                             String barcodeSuffix,
                             int barcodeStartIndex,
                             int barcodeEndIndex);
    Messaging gateway interface:
    Code:
        
        Future<ResultObject<CartridgeResults>> getCartridges(CartridgeServiceParms parms);
    When I try to execute a test call on this gateway, there is an error. The gateways are built, but there is an error processing the service activator:
    java.lang.IllegalArgumentException: Found ambiguous parameter type [class parms.CartridgeServiceParms] for method match: [public java.lang.String com.sepaton.vtl.api.gateway.core.contracts.activat ors.CartridgeServiceServiceActivator.getCartInfoFo rLibrary(parms.CartridgeServiceParms)]
    I've seen this error in other threads, but older ones, and reports that the error has been fixed. Does anyone know what this could be?

  2. #2

    Default

    The problem appears to be in the class MethodMethodInvokerHelper (integration core, 2.1.0.RELEASE). I'm so baffled by this that it must be a misunderstanding on my part. It seems that methods in a ServiceActivator must have unique parameter types, even though there are unique names to the methods. OR, maybe there can only be one method in a service activator, and I have to create unique service activators for each gateway method. I'm not sure, but the class as I understand it won't work for my situation. In the face of having no idea on this, I am going the route of creating a unique parameter signature for each activator method, but I have a feeling that another problem will surface, as I am most likely missing the intent.

  3. #3
    Join Date
    Oct 2005
    Location
    Boston, MA
    Posts
    2,840

    Default

    You can specify a 'method' attribute in the <service-activator> element.

  4. #4
    Join Date
    Jan 2008
    Location
    Mohnton, PA USA (that's near Philadelphia)
    Posts
    2,148

    Default

    I just wanted to add a few things to what Mark said. It might eb a bit philosophical.
    We tend to call Java classes as services but unless they are designed as services they are not. Think about it. If you have a class that has multiple public methods where each method represents some independent functionality - each method is actually a service and the class is a collection of services. It is not a service in itself. However if you want to design a class to be a service than it could *only* have one pubic method (besides toString, hashCode etc. which we handle).
    So the exception you are seeing is simply stating that we can't figure out which method do you want us to invoke since we've determined that more than one method *could be* invoked based on the incoming Message state.

    So explicitly specifying which method via 'method' attribute solves the problem

    Hope that helps

  5. #5

    Default

    I appreciate both replies and the explanation. It was definitely a misunderstanding on my part. I was thinking that the activator could have multiple methods much the same as the gateway. My idea of a service is based on the way services are offered in the environment where I work. I was able to move beyond this once I created a unique service-activator for each gateway method, and changed the gateway to not have a default-request-channel and shifted to having a request-channel for each gateway method.

    Thanks, this bailed me out.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •