Announcement Announcement Module
Collapse
No announcement yet.
Using Spel Expressions in service activators Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Using Spel Expressions in service activators

    Our Integration services have a few setters and getters for various other services. I wish to use spel expressions to invoke only one (always one) of the actual method in any of the integration services.
    The normal way of using service activators with the method attribute works fine. But i wish to return any type of Object from the integration service and using the spel expression in the next service activator to invoke the required method. But this leads to ambiguity.
    Caused by: java.lang.IllegalArgumentException: Found ambiguous parameter type
    example
    Code:
    public class AService {
    	BService bService;
    	CService cService;
    	public CService getcService() {
    		return cService;
    	}
    	public void setcService(CService cService) {
    		this.cService = cService;
    	}
    
    	public BService getbService() {
    		return bService;
    	}
    
    	public void setbService(BService bService) {
    		this.bService = bService;
    	}
    	@Transactional()
    	public void doBusiness1(String anything)
    	{
    		System.out.println("AServiceBusiness1");
    	}
    	
    }
    Code:
    public class CService { }
    
    public class BService { }
    
    public class SomePayload
    {
    	String anything;
    
    	public String getAnything() {
    		return anything;
    	}
    
    	public void setAnything(String anything) {
    		this.anything = anything;
    	}
    }
    Code:
    	<int:channel id="input"/>
    	<bean id="bService" class="a.b.c.BService"/>
    	<bean id="cService" class="a.b.c.CService"/>
    	<bean id="aService" class="a.b.c.AService">
    		<property name="bService" ref="bService"/>
    		<property name="cService" ref="cService"/>
    	</bean>
    	<int:service-activator input-channel="input" ref="aService" expression="payload.anything" output-channel="logChannel"/>
    Code:
    MessageChannel inputChannel = appContext.getBean("input", MessageChannel.class);
    SomePayload somePayload = new SomePayload();
    somePayload.setAnything("something");
    Message msg = MessageBuilder.withPayload(somePayload).build();
    inputChannel.send(msg);
    results in
    Caused by: java.lang.IllegalArgumentException: Found ambiguous parameter type [interface java.util.List] for method match: [public void a.b.c.AService.doBusiness1(java.lang.String), public void a.b.c.AService.setcService(a.b.c.CService), public void a.b.c.AService.setbService(a.b.c.BService), public a.b.c.BService a.b.c.AService.getbService()]
    I had thought that based on the expression result the appropriate method would be invoked ?
    I did not want to use multiple transformers (with their own channels) as they will all essentially be extracting the required attribute from the payload to invoke the next service.

    Thanks in advance

  • #2
    Hello
    You have several bugs in your configuration:
    1. If you wat to send reply Message to output-channel your service method should not be void. You must return some object which will be as payload of reply message or full message via MessageBuilder
    2. You got IllegalArgumentException because you didn't specify any service method in the attribute method. Or you can mark your doBusiness1 with @ServiceActivator. But if you have several business methods in service there is only one way to specify service method for service-activator - declare it in method attribute.
    3. And the last one: it will be a new configuration Exception on parsing your service-activator. You can specify ref attribute or expression, but only just one from them. The value of expression will configured as service method.

    Please, read the SI-manual

    Good luck,
    Artem

    Comment


    • #3
      1. my typo
      2. i was under the impression that specifying the expression would find the appropriate method to invoke, as in if given a payload the appropriate method with the payload as the argument would be invoked.
      but yes ref or expression.
      Code:
      	<int:service-activator input-channel="aChannel" expression="@aService.doBusiness1(payload)"   output-channel="logChannel"/>

      Comment


      • #4
        You must write like this:
        Code:
         expression="@aService.doBusiness1(payload.anything)"
        Because your service method accepts the parameter of type String, but your payload is SomePayload

        Comment

        Working...
        X