0
votes

I am getting following exception when used atomikos transaction manager with spring integration

14:36:18.182 DEBUG [main][org.springframework.integration.jms.JmsSendingMessageHandler] org.springframework.integration.jms.JmsSendingMessageHandler#0 received message: [Payload=EmployeeRecord{name='Rmex123', address=Phoenix, AZ}][Headers={timestamp=1403732178182, id=95b13ba2-3b22-4724-8d8d-d3d98c39a694}]
14:36:18.241 WARN  [main][com.atomikos.jms.ConsumerProducerSupport] atomikos MessageProducer proxy for ActiveMQMessageProducer { value=ID:PHXJ05376352-13260-1403732176990-1:1:2:1 }: The JMS session you are using requires a JTA transaction context for the calling thread and none was found.
Please correct your code to do one of the following: 
1. start a JTA transaction if you want your JMS operations to be subject to JTA commit/rollback, or
2. increase the maxPoolSize of the AtomikosConnectionFactoryBean to avoid transaction timeout while waiting for a connection, or
3. create a non-transacted session and do session acknowledgment yourself, or
4. set localTransactionMode to true so connection-level commit/rollback are enabled.
14:36:18.242 WARN  [main][com.atomikos.jms.AtomikosTransactionRequiredJMSException] The JMS session you are using requires a JTA transaction context for the calling thread and none was found.
Please correct your code to do one of the following: 
1. start a JTA transaction if you want your JMS operations to be subject to JTA commit/rollback, or
2. increase the maxPoolSize of the AtomikosConnectionFactoryBean to avoid transaction timeout while waiting for a connection, or
3. create a non-transacted session and do session acknowledgment yourself, or
4. set localTransactionMode to true so connection-level commit/rollback are enabled.
Exception in thread "main" org.springframework.integration.MessageHandlingException: error occurred in message handler [org.springframework.integration.jms.JmsSendingMessageHandler#0]
    at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:79)

Am I missing something here? Do i need to start a JTA transaction explicitly Please help to resolve this

<context:component-scan base-package="com.mycompany.poc.sif" />

<int:publish-subscribe-channel id="reqChannel"/> 
<int:channel id="jmsChannel" />



<int:service-activator   input-channel="inChannel" ref="serviceHandler" output-channel="inUnmarshalChannel" />
<!-- To convert incoming XML to EmployeeRecord -->
<int-xml:unmarshalling-transformer unmarshaller="unMarshaller" input-channel="inUnmarshalChannel" output-channel="reqChannel"/>

<!-- To perform Database insert  -->
<jdbc:outbound-channel-adapter channel="reqChannel" query="insert into EMPLOYEERECORD(name,address) values (:payload.name, :payload.address)" data-source="atomikos.dataSource" />

    <!-- To perform JMS Queue send   -->
<int:object-to-string-transformer input-channel="reqChannel" output-channel="jmsChannel"/>
<jms:outbound-channel-adapter id="jms" jms-template="jmsTemplate" channel="jmsChannel" /> 

    <!-- To perform BG check Service Call    -->
<int:transformer ref="bgCheckTransformerBean" input-channel="reqChannel" output-channel="headerChannel"/>
<ws:header-enricher input-channel="headerChannel" output-channel="wsChannel">
    <ws:soap-action value="http://www.example.org/wspBackGroundcheckService/backGroundCheck" />
</ws:header-enricher>
<ws:outbound-gateway id="bgcheckGateway" request-channel="wsChannel" reply-channel="outChannel"
            marshaller="jaxbMarshaller" unmarshaller="jaxbMarshaller" uri="http://host1:3057/BackGroundcheckService" />

<int:header-filter header-names="ws_soapAction" input-channel="outChannel" output-channel="respChannel" />
<int:transformer ref="responseTransformerBean" input-channel="respChannel" output-channel="endChannel"/>

<!--    Bean definitions -->

<beans:bean id="serviceHandler" class="com.mycompany.poc.sif.service.EmpOnboardService" />

<beans:bean id="jaxbMarshaller"
    class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
    <beans:property name="contextPaths"
                value="org.example.backgroundcheckservice" />
    <beans:property name="checkForXmlRootElement" value="false" />
</beans:bean>

<beans:bean id="unMarshaller"
            class="org.springframework.oxm.castor.CastorMarshaller">
    <beans:property name="mappingLocation" value="classpath:mapping.xml" />
</beans:bean>

<beans:bean id="payloadTransformerBean"
            class="com.mycompany.poc.sif.transformer.PayloadTransformer" />
<beans:bean id="bgCheckTransformerBean"
            class="com.mycompany.poc.sif.transformer.BGCheckTransformer" />
<beans:bean id="responseTransformerBean"
            class="com.mycompany.poc.sif.transformer.ResponseTransformer" />


<beans:bean id="db2.datasource" class="com.ibm.db2.jcc.DB2XADataSource">
    <beans:property name="serverName" value="hostname" />
    <beans:property name="portNumber" value="1234" />
    <beans:property name="databaseName" value="ADB" />
    <beans:property name="driverType" value="4" />
    <beans:property name="user" value="user" />
    <beans:property name="password" value="passwd" />
</beans:bean>




<!--     Define JMS template -->        
    <beans:bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
        <beans:property name="connectionFactory" ref="atomikos.connectionFactory"></beans:property>
         <beans:property name="defaultDestination" ref="requestQueue"></beans:property>
        <beans:property name="sessionTransacted" value="true"></beans:property>
    </beans:bean>  


    <beans:bean id="requestQueue" class="org.apache.activemq.command.ActiveMQQueue">
            <beans:constructor-arg value="queue.sif"/>
    </beans:bean>


        <!--     Define Transaction Manager and User Transaction -->
        <beans:bean id="jta.transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager">
            <beans:property name="transactionManager" ref="atomikos.transactionManager"/>
            <beans:property name="userTransaction" ref="atomikos.userTransaction"/>
        </beans:bean>

            <!-- javax.transaction.TransactionManager -->
        <beans:bean id="atomikos.transactionManager" class="com.atomikos.icatch.jta.UserTransactionManager"
              init-method="init" destroy-method="close">
            <beans:property name="forceShutdown" value="false"/>
        </beans:bean>

        <!-- javax.transaction.UserTransaction -->
        <beans:bean id="atomikos.userTransaction"
              class="com.atomikos.icatch.jta.UserTransactionImp">
            <beans:property name="transactionTimeout" value="3000"/>
        </beans:bean>

        <!--Wrap the JMS here-->
        <!-- Atomikos JTA configuration, nothing specific to Spring here -->
        <beans:bean id="atomikos.connectionFactory" class="com.atomikos.jms.AtomikosConnectionFactoryBean"
              init-method="init" destroy-method="close">
            <beans:property name="uniqueResourceName" value="xa.activemq"/>
            <beans:property name="xaConnectionFactory" ref="xa.connectionFactory"/>
            <beans:property name="localTransactionMode" value="false"/>
            <!-- XAConnectionFactory -->
            <beans:property name="maxPoolSize" value="10"/>
        </beans:bean>
        <beans:bean id="xa.connectionFactory" class="org.apache.activemq.ActiveMQXAConnectionFactory">
            <beans:property name="brokerURL" value="tcp://localhost:61616"/>
            <beans:property name="userName" value="admin"/>
            <beans:property name="password" value="admin"/>
        </beans:bean>

        <!-- Wrap the DB datasources-->
        <beans:bean id="atomikos.dataSource" class="com.atomikos.jdbc.AtomikosDataSourceBean">
            <beans:property name="uniqueResourceName" value="xa.db2"/>
            <beans:property name="xaDataSource" ref="db2.datasource"/>
            <!-- XADataSource -->
        </beans:bean>

    <stream:stdout-channel-adapter id="endChannel" />

Error


:16:14.486 DEBUG [main][org.springframework.integration.channel.DirectChannel] preSend on channel 'inUnmarshalChannel', message: [Payload=Rmex123Phoenix, AZ][Headers={timestamp=1403738174485, id=5cdf38dc-1c45-4392-a7c7-7b2caf586701}]
16:16:14.486 DEBUG [main][org.springframework.integration.transformer.MessageTransformingHandler] org.springframework.integration.transformer.MessageTransformingHandler#0 received message: [Payload=Rmex123Phoenix, AZ][Headers={timestamp=1403738174485, id=5cdf38dc-1c45-4392-a7c7-7b2caf586701}]
16:16:14.496 DEBUG [main][org.springframework.integration.transformer.MessageTransformingHandler] handler 'org.springframework.integration.transformer.MessageTransformingHandler#0' sending reply Message: [Payload=EmployeeRecord{name='Rmex123', address=Phoenix, AZ}][Headers={timestamp=1403738174496, id=93d53947-5564-4bf1-bc7c-a4471c185b88}]
16:16:14.496 DEBUG [main][org.springframework.integration.channel.PublishSubscribeChannel] preSend on channel 'reqChannel', message: [Payload=EmployeeRecord{name='Rmex123', address=Phoenix, AZ}][Headers={timestamp=1403738174496, id=93d53947-5564-4bf1-bc7c-a4471c185b88}]
16:16:14.496 DEBUG [main][org.springframework.integration.jdbc.JdbcMessageHandler] org.springframework.integration.jdbc.JdbcMessageHandler#0 received message: [Payload=EmployeeRecord{name='Rmex123', address=Phoenix, AZ}][Headers={timestamp=1403738174496, id=93d53947-5564-4bf1-bc7c-a4471c185b88}]
16:16:14.517 WARN  [main][com.atomikos.jdbc.AbstractDataSourceBean] AtomikosDataSoureBean 'xa.db2': poolSize equals default - this may cause performance problems!
16:16:15.758 DEBUG [main][org.springframework.integration.jdbc.JdbcMessageHandler] Generated keys: [{UPDATED=1}]
16:16:15.758 DEBUG [main][org.springframework.integration.transformer.MessageTransformingHandler] org.springframework.integration.transformer.MessageTransformingHandler#1 received message: [Payload=EmployeeRecord{name='Rmex123', address=Phoenix, AZ}][Headers={timestamp=1403738174496, id=93d53947-5564-4bf1-bc7c-a4471c185b88}]
16:16:15.758 DEBUG [main][org.springframework.integration.transformer.MessageTransformingHandler] handler 'org.springframework.integration.transformer.MessageTransformingHandler#1' sending reply Message: [Payload=EmployeeRecord{name='Rmex123', address=Phoenix, AZ}][Headers={timestamp=1403738175758, id=809a9316-3c1d-474c-879f-eddbbb82fb2f}]
16:16:15.758 DEBUG [main][org.springframework.integration.channel.DirectChannel] preSend on channel 'jmsChannel', message: [Payload=EmployeeRecord{name='Rmex123', address=Phoenix, AZ}][Headers={timestamp=1403738175758, id=809a9316-3c1d-474c-879f-eddbbb82fb2f}]
16:16:15.758 DEBUG [main][org.springframework.integration.jms.JmsSendingMessageHandler] org.springframework.integration.jms.JmsSendingMessageHandler#0 received message: [Payload=EmployeeRecord{name='Rmex123', address=Phoenix, AZ}][Headers={timestamp=1403738175758, id=809a9316-3c1d-474c-879f-eddbbb82fb2f}]
16:16:15.809 WARN  [main][com.atomikos.jms.ConsumerProducerSupport] atomikos MessageProducer proxy for ActiveMQMessageProducer { value=ID:PHXJ05376352-15248-1403738173579-1:1:2:1 }: The JMS session you are using requires a JTA transaction context for the calling thread and none was found.
Please correct your code to do one of the following: 
1. start a JTA transaction if you want your JMS operations to be subject to JTA commit/rollback, or
2. increase the maxPoolSize of the AtomikosConnectionFactoryBean to avoid transaction timeout while waiting for a connection, or
3. create a non-transacted session and do session acknowledgment yourself, or
4. set localTransactionMode to true so connection-level commit/rollback are enabled.
16:16:15.809 WARN  [main][com.atomikos.jms.AtomikosTransactionRequiredJMSException] The JMS session you are using requires a JTA transaction context for the calling thread and none was found.
Please correct your code to do one of the following: 
1. start a JTA transaction if you want your JMS operations to be subject to JTA commit/rollback, or
2. increase the maxPoolSize of the AtomikosConnectionFactoryBean to avoid transaction timeout while waiting for a connection, or
3. create a non-transacted session and do session acknowledgment yourself, or
4. set localTransactionMode to true so connection-level commit/rollback are enabled.
Exception in thread "main" org.springframework.integration.MessageHandlingException: error occurred in message handler [org.springframework.integration.jms.JmsSendingMessageHandler#0]
    at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:79)
    at org.springframework.integration.dispatcher.UnicastingDispatcher.doDispatch(UnicastingDispatcher.java:115)
    at org.springframework.integration.dispatcher.UnicastingDispatcher.dispatch(UnicastingDispatcher.java:102)
    at org.springframework.integration.channel.AbstractSubscribableChannel.doSend(AbstractSubscribableChannel.java:77)
    at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:157)
    at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:128)
    at org.springframework.integration.core.MessagingTemplate.doSend(MessagingTemplate.java:288)
    at org.springframework.integration.core.MessagingTemplate.send(MessagingTemplate.java:149)
    at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.sendMessage(AbstractReplyProducingMessageHandler.java:216)
    at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.sendReplyMessage(AbstractReplyProducingMessageHandler.java:200)
    at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.produceReply(AbstractReplyProducingMessageHandler.java:165)
    at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.handleResult(AbstractReplyProducingMessageHandler.java:159)
    at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.handleMessageInternal(AbstractReplyProducingMessageHandler.java:141)
    at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:73)
    at org.springframework.integration.dispatcher.BroadcastingDispatcher.invokeHandler(BroadcastingDispatcher.java:121)
    at org.springframework.integration.dispatcher.BroadcastingDispatcher.dispatch(BroadcastingDispatcher.java:112)
    at org.springframework.integration.channel.AbstractSubscribableChannel.doSend(AbstractSubscribableChannel.java:77)
    at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:157)
    at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:128)
    at org.springframework.integration.core.MessagingTemplate.doSend(MessagingTemplate.java:288)
    at org.springframework.integration.core.MessagingTemplate.send(MessagingTemplate.java:149)
    at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.sendMessage(AbstractReplyProducingMessageHandler.java:216)
    at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.sendReplyMessage(AbstractReplyProducingMessageHandler.java:200)
    at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.produceReply(AbstractReplyProducingMessageHandler.java:165)
    at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.handleResult(AbstractReplyProducingMessageHandler.java:159)
    at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.handleMessageInternal(AbstractReplyProducingMessageHandler.java:141)
    at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:73)
    at org.springframework.integration.dispatcher.UnicastingDispatcher.doDispatch(UnicastingDispatcher.java:115)
    at org.springframework.integration.dispatcher.UnicastingDispatcher.dispatch(UnicastingDispatcher.java:102)
    at org.springframework.integration.channel.AbstractSubscribableChannel.doSend(AbstractSubscribableChannel.java:77)
    at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:157)
    at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:128)
    at org.springframework.integration.core.MessagingTemplate.doSend(MessagingTemplate.java:288)
    at org.springframework.integration.core.MessagingTemplate.send(MessagingTemplate.java:149)
    at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.sendMessage(AbstractReplyProducingMessageHandler.java:216)
    at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.sendReplyMessage(AbstractReplyProducingMessageHandler.java:200)
    at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.produceReply(AbstractReplyProducingMessageHandler.java:165)
    at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.handleResult(AbstractReplyProducingMessageHandler.java:159)
    at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.handleMessageInternal(AbstractReplyProducingMessageHandler.java:141)
    at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:73)
    at org.springframework.integration.dispatcher.UnicastingDispatcher.doDispatch(UnicastingDispatcher.java:115)
    at org.springframework.integration.dispatcher.UnicastingDispatcher.dispatch(UnicastingDispatcher.java:102)
    at org.springframework.integration.channel.AbstractSubscribableChannel.doSend(AbstractSubscribableChannel.java:77)
    at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:157)
    at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:128)
    at com.amex.poc.sif.main.TransactionTestApp.main(TransactionTestApp.java:29)
Caused by: org.springframework.jms.UncategorizedJmsException: Uncategorized exception occured during JMS processing; nested exception is com.atomikos.jms.AtomikosTransactionRequiredJMSException: The JMS session you are using requires a JTA transaction context for the calling thread and none was found.
Please correct your code to do one of the following: 
1. start a JTA transaction if you want your JMS operations to be subject to JTA commit/rollback, or
2. increase the maxPoolSize of the AtomikosConnectionFactoryBean to avoid transaction timeout while waiting for a connection, or
3. create a non-transacted session and do session acknowledgment yourself, or
4. set localTransactionMode to true so connection-level commit/rollback are enabled.
    at org.springframework.jms.support.JmsUtils.convertJmsAccessException(JmsUtils.java:316)
    at org.springframework.jms.support.JmsAccessor.convertJmsAccessException(JmsAccessor.java:169)
    at org.springframework.jms.core.JmsTemplate.execute(JmsTemplate.java:494)
    at org.springframework.jms.core.JmsTemplate.send(JmsTemplate.java:566)
    at org.springframework.jms.core.JmsTemplate.convertAndSend(JmsTemplate.java:689)
    at org.springframework.jms.core.JmsTemplate.convertAndSend(JmsTemplate.java:677)
    at org.springframework.integration.jms.JmsSendingMessageHandler.send(JmsSendingMessageHandler.java:145)
    at org.springframework.integration.jms.JmsSendingMessageHandler.handleMessageInternal(JmsSendingMessageHandler.java:112)
    at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:73)
    ... 45 more
Caused by: com.atomikos.jms.AtomikosTransactionRequiredJMSException: The JMS session you are using requires a JTA transaction context for the calling thread and none was found.
Please correct your code to do one of the following: 
1. start a JTA transaction if you want your JMS operations to be subject to JTA commit/rollback, or
2. increase the maxPoolSize of the AtomikosConnectionFactoryBean to avoid transaction timeout while waiting for a connection, or
3. create a non-transacted session and do session acknowledgment yourself, or
4. set localTransactionMode to true so connection-level commit/rollback are enabled.
    at com.atomikos.jms.AtomikosTransactionRequiredJMSException.throwAtomikosTransactionRequiredJMSException(AtomikosTransactionRequiredJMSException.java:40)
    at com.atomikos.jms.ConsumerProducerSupport.enlist(ConsumerProducerSupport.java:112)
    at com.atomikos.jms.AtomikosJmsMessageProducerProxy.send(AtomikosJmsMessageProducerProxy.java:52)
    at com.atomikos.jms.AtomikosJmsMessageProducerProxy.send(AtomikosJmsMessageProducerProxy.java:133)
    at org.springframework.jms.core.JmsTemplate.doSend(JmsTemplate.java:633)
    at org.springframework.jms.core.JmsTemplate.doSend(JmsTemplate.java:604)
    at org.springframework.jms.core.JmsTemplate$3.doInJms(JmsTemplate.java:569)
    at org.springframework.jms.core.JmsTemplate.execute(JmsTemplate.java:491)
    ... 51 more


This is my main Method from which i pass the message to channel
************************************************************
    public static void main(String[] args) {
        final String[] configFiles = {"/META-INF/spring/integration/spring-integration-context-standalone.xml"
        };
        ClassPathXmlApplicationContext context =
            new ClassPathXmlApplicationContext(configFiles,TransactionTestApp.class);
        BeanFactoryChannelResolver channelResolver = new BeanFactoryChannelResolver(context);

        // Compose the XML message according to the server's schema
        String requestXml =
                ""
                +"Rat123"
                +"Phoenix, AZ"
                +"";

        // Create the Message object
        //org.springframework.integration.Message message =MessageBuilder.withPayload(requestXml).build();
        org.springframework.integration.Message message = MessageBuilder.withPayload(requestXml).build();
        // Send the Message to the handler's input channel
        org.springframework.integration.MessageChannel channel = channelResolver.resolveChannelName("inChannel");
        channel.send((org.springframework.integration.Message) message);

    }

1
You need to show your Spring Integration configuration and post the complete stacktrace somewhere. How are you sending data to the jms outbound endpoint? The answer will depend on that information. - Gary Russell
hi Gary , How do i sent the Spring configuration? Is there a place in this site ti attach a file - Rathnesh
You can paste configuration in your question or in a github gist; the stack trace (if large) should go somewhere else (like pastebin). - Gary Russell
Hi Gary, Spring config file and exception stack trace added - Rathnesh
You didn't show how messages get into inChannel - something upstream of that needs to start the transaction. - Gary Russell

1 Answers

0
votes

You need to start the transaction.

Instead of simply sending the message to inChannel, consider using a Messaging Gateway; annotate it as @Transactional and the framework will start the transaction.

If you must send to the channel, do it within a TransactionTemplate.execute() method.

EDIT:

If the flow starts with a polled inbound adapter, mark the poller with <transactional/>.

If the flow starts with a non-transactional message-driven adapter (e.g., WS, HTTP) you need to insert a transactional gateway to scope the transaction...

public interface TxGate {

    @Transactional
    Message<?> exchange(Message<?> message);
}

<int-ws:inbound-gateway ... requestChannel="startTx" ... />

<int:service-activator input-channel="startTx" ref="txGate" />

<int:gateway id="txGate" request-channel="onward" service=interface="foo.TxGate" />
Error when tried to do the above
*************************************\
15:09:03.664 INFO  [main][org.springframework.integration.gateway.GatewayProxyFactoryBean$MethodInvocationGateway] started onboardService
15:09:03.664 INFO  [main][org.springframework.integration.gateway.GatewayProxyFactoryBean] started onboardService
15:09:03.695 DEBUG [main][org.springframework.integration.util.MessagingMethodInvokerHelper] Method [public final void com.sun.proxy.$Proxy21.addAdvice(int,org.aopalliance.aop.Advice) throws org.springframework.aop.framework.AopConfigException] is not eligible for Message handling.
java.lang.IllegalArgumentException: Found more than one parameter type candidate: [int] and [org.aopalliance.aop.Advice]
    at org.springframework.util.Assert.isNull(Assert.java:89)
    at org.springframework.integration.util.MessagingMethodInvokerHelper$HandlerMethod.setExclusiveTargetParameterType(MessagingMethodInvokerHelper.java:624)
    at org.springframework.integration.util.MessagingMethodInvokerHelper$HandlerMethod.generateExpression(MessagingMethodInvokerHelper.java:558)
    at org.springframework.integration.util.MessagingMethodInvokerHelper$HandlerMethod.(MessagingMethodInvokerHelper.java:440)
    at org.springframework.integration.util.MessagingMethodInvokerHelper$1.doWith(MessagingMethodInvokerHelper.java:302)
    at org.springframework.util.ReflectionUtils.doWithMethods(ReflectionUtils.java:480)
    at org.springframework.integration.util.MessagingMethodInvokerHelper.findHandlerMethodsForTarget(MessagingMethodInvokerHelper.java:276)
    at org.springframework.integration.util.MessagingMethodInvokerHelper.(MessagingMethodInvokerHelper.java:169)
    at org.springframework.integration.util.MessagingMethodInvokerHelper.(MessagingMethodInvokerHelper.java:121)
    at org.springframework.integration.util.MessagingMethodInvokerHelper.(MessagingMethodInvokerHelper.java:116)
    at org.springframework.integration.handler.MethodInvokingMessageProcessor.(MethodInvokingMessageProcessor.java:56)
    at org.springframework.integration.handler.ServiceActivatingHandler.(ServiceActivatingHandler.java:35)
    at org.springframework.integration.config.ServiceActivatorFactoryBean.createMethodInvokingHandler(ServiceActivatorFactoryBean.java:48)
    at org.springframework.integration.config.AbstractStandardMessageHandlerFactoryBean.createHandler(AbstractStandardMessageHandlerFactoryBean.java:72)
    at org.springframework.integration.config.AbstractSimpleMessageHandlerFactoryBean.createHandlerInternal(AbstractSimpleMessageHandlerFactoryBean.java:99)
    at org.springframework.integration.config.AbstractSimpleMessageHandlerFactoryBean.getObject(AbstractSimpleMessageHandlerFactoryBean.java:81)

Adding method="exchange" to the service activator should solve this.