Reputation: 1323
I am using spring-boot and spring integration to receive emails and save attachments into files .
I used PseudoTransactionManager because i wanted to raise an exception and role back if the email have no attachment (in role back i am moving the email to failed folder and on commit i move it to success folder).
@Bean(name="emailTransactionManager")
public PseudoTransactionManager emailTransactionManager() {
return new PseudoTransactionManager();
}
@Bean(name="transactionManager")
@Primary
public PlatformTransactionManager transactionManager() {
return new JpaTransactionManager();
}
Every thing is working good except when i role back i got the below error .
2015-12-09 21:01:03.388 INFO 874 --- [ask-scheduler-1] o.s.integration.mail.ImapMailReceiver : attempting to receive mail from folder [INBOX]
2015-12-09 21:01:04.767 INFO 874 --- [pool-3-thread-1] c.t.r.m.support.EmailTransformer : Email contains 1 fragments.
2015-12-09 21:01:04.772 ERROR 874 --- [pool-3-thread-1] o.s.integration.handler.LoggingHandler : org.springframework.messaging.MessageHandlingException: nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [org.springframework.transaction.PlatformTransactionManager] is defined: expected single matching bean but found 2: emailTransactionManager,transactionManager
at org.springframework.integration.handler.MethodInvokingMessageProcessor.processMessage(MethodInvokingMessageProcessor.java:96)
at org.springframework.integration.splitter.AbstractMessageProcessingSplitter.splitMessage(AbstractMessageProcessingSplitter.java:61)
at org.springframework.integration.splitter.AbstractMessageSplitter.handleRequestMessage(AbstractMessageSplitter.java:55)
at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.handleMessageInternal(AbstractReplyProducingMessageHandler.java:99)
at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:127)
at org.springframework.integration.handler.MessageHandlerChain$1.send(MessageHandlerChain.java:123)
at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:115)
at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:45)
at org.springframework.messaging.core.AbstractMessageSendingTemplate.send(AbstractMessageSendingTemplate.java:105)
at org.springframework.integration.handler.AbstractMessageProducingHandler.sendOutput(AbstractMessageProducingHandler.java:231)
at org.springframework.integration.handler.AbstractMessageProducingHandler.produceOutput(AbstractMessageProducingHandler.java:154)
at org.springframework.integration.handler.AbstractMessageProducingHandler.sendOutputs(AbstractMessageProducingHandler.java:102)
at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.handleMessageInternal(AbstractReplyProducingMessageHandler.java:105)
at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:127)
at org.springframework.integration.handler.MessageHandlerChain.handleMessageInternal(MessageHandlerChain.java:104)
at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:127)
at org.springframework.integration.dispatcher.AbstractDispatcher.tryOptimizedDispatch(AbstractDispatcher.java:116)
at org.springframework.integration.dispatcher.UnicastingDispatcher.doDispatch(UnicastingDispatcher.java:147)
at org.springframework.integration.dispatcher.UnicastingDispatcher.dispatch(UnicastingDispatcher.java:120)
at org.springframework.integration.channel.AbstractSubscribableChannel.doSend(AbstractSubscribableChannel.java:77)
at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:442)
at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:392)
at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:115)
at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:45)
at org.springframework.messaging.core.AbstractMessageSendingTemplate.send(AbstractMessageSendingTemplate.java:105)
at org.springframework.integration.endpoint.MessageProducerSupport.sendMessage(MessageProducerSupport.java:105)
at org.springframework.integration.mail.ImapIdleChannelAdapter.access$2300(ImapIdleChannelAdapter.java:62)
at org.springframework.integration.mail.ImapIdleChannelAdapter$1.run(ImapIdleChannelAdapter.java:269)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:302)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:281)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:208)
at com.sun.proxy.$Proxy83.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [org.springframework.transaction.PlatformTransactionManager] is defined: expected single matching bean but found 2: emailTransactionManager,transactionManager
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:366)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:332)
at org.springframework.transaction.interceptor.TransactionAspectSupport.determineTransactionManager(TransactionAspectSupport.java:367)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:271)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:654)
at com.teltacworldwide.rateserver.mailattachments.support.EmailSplitter$$EnhancerBySpringCGLIB$$d5a16c5e.splitIntoMessages(<generated>)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at org.springframework.expression.spel.support.ReflectiveMethodExecutor.execute(ReflectiveMethodExecutor.java:113)
at org.springframework.expression.spel.ast.MethodReference.getValueInternal(MethodReference.java:129)
at org.springframework.expression.spel.ast.MethodReference.access$000(MethodReference.java:49)
at org.springframework.expression.spel.ast.MethodReference$MethodValueRef.getValue(MethodReference.java:342)
at org.springframework.expression.spel.ast.CompoundExpression.getValueInternal(CompoundExpression.java:88)
at org.springframework.expression.spel.ast.SpelNodeImpl.getTypedValue(SpelNodeImpl.java:131)
at org.springframework.expression.spel.standard.SpelExpression.getValue(SpelExpression.java:330)
at org.springframework.integration.util.AbstractExpressionEvaluator.evaluateExpression(AbstractExpressionEvaluator.java:166)
at org.springframework.integration.util.MessagingMethodInvokerHelper.processInternal(MessagingMethodInvokerHelper.java:317)
at org.springframework.integration.util.MessagingMethodInvokerHelper.process(MessagingMethodInvokerHelper.java:155)
at org.springframework.integration.handler.MethodInvokingMessageProcessor.processMessage(MethodInvokingMessageProcessor.java:93)
... 43 more
2015-12-09 21:01:04.774 INFO 874 --- [pool-3-thread-1] c.t.r.mailattachments.support.ImapMove : Moving message <[email protected]> to success folder
I don't know if it is a spring-boot or integration but logging-adapter is subscribed to errorChannel and it can't autowire transactionManager i tried to annotate transactionManager with @Primary but it did not work
Integration XML
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:int="http://www.springframework.org/schema/integration"
xmlns:int-file="http://www.springframework.org/schema/integration/file"
xmlns:int-mail="http://www.springframework.org/schema/integration/mail"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:int-stream="http://www.springframework.org/schema/integration/stream"
xsi:schemaLocation="http://www.springframework.org/schema/integration/stream http://www.springframework.org/schema/integration/stream/spring-integration-stream-4.2.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/integration/file http://www.springframework.org/schema/integration/file/spring-integration-file.xsd
http://www.springframework.org/schema/integration/mail http://www.springframework.org/schema/integration/mail/spring-integration-mail.xsd
http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
<int:transaction-synchronization-factory
id="syncFactory">
<int:after-commit expression="@imapMove.success(payload)" />
<int:after-rollback expression="@imapMove.fail(payload)" />
</int:transaction-synchronization-factory>
<int-mail:imap-idle-channel-adapter
id="poll-for-email" channel="emailChannel" java-mail-properties="javaMailProperties"
store-uri="imaps://xxxxxxx\test:[email protected]/INBOX"
should-delete-messages="false" error-channel="failed-email-fetch" auto-startup="true">
<int-mail:transactional transaction-manager="emailTransactionManager" synchronization-factory="syncFactory"/>
</int-mail:imap-idle-channel-adapter>
<util:properties id="javaMailProperties">
<prop key="mail.store.protocol">imaps</prop>
<prop key="mail.pop3.starttls.enable">true</prop>
<prop key="mail.pop3.ssl.trust">exchange.xxxxxxx.co</prop>
<prop key="mail.imaps.starttls.enable">true</prop>
<prop key="mail.imaps.ssl.trust">exchange.xxxxxxx.co</prop>
<prop key="mail.smtp.starttls.enable">true</prop>
<prop key="mail.smtp.ssl.trust">exchange.xxxxxxx.co</prop>
<prop key="mail.debug">false</prop>
</util:properties>
<int:channel id="emailChannel" />
<int:chain id="transform-split-save" input-channel="emailChannel"
output-channel="jobChannel">
<int:transformer ref="emailTransformer" />
<int:splitter ref="emailSplitter" />
<int:header-enricher ref="carrierEnricher" method="addCarrier" />
<int-file:outbound-gateway id="save-as-file"
auto-create-directory="true"
directory-expression="'target/out/' + headers.directory" />
</int:chain>
<!-- <int-file:outbound-channel-adapter id="save-as-file" auto-create-directory="true"
channel="outputChannel" directory-expression="'target/out/' + headers.directory"/> -->
<int:channel id="jobChannel" />
<int-stream:stdout-channel-adapter channel="jobChannel">
</int-stream:stdout-channel-adapter>
<int:exception-type-router input-channel="failed-email-fetch" default-output-channel="errorChannel">
<int:mapping exception-type="com.xxxxxxx.rateserver.exception.RateException"
channel="customError" />
</int:exception-type-router>
<int:channel id="failed-email-fetch" />
<int:channel id="customError" />
<int:service-activator input-channel="customError" ref="emailError" method="onEmailFetchFailed" />
</beans>
Upvotes: 1
Views: 300
Reputation: 1323
I found the problem, on the splitter the method was annotated with @Transactional
so it was using default transactionManager
.
To confirm I tried it with @Transactional(transactionManager="emailTranasactionmanager")
and it worked. In my case I just removed the @Transaction
as I need only one transaction.
Upvotes: 1