根据我的理解,ServiceActivator中的运行时异常应该向errorChannel发送消息。
但是如果没有设置errorHandler,那么这不起作用。我甚至试图设置errorHandler
<bean id="translatorContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="connectionFactory" ref="connectionFactory" />
<property name="errorHandler" ref="myErrorHandler"/>
<property name="destination" ref="TRANSLATED-MDCAD" />
<property name="sessionTransacted" value="true" />
<property name="maxConcurrentConsumers" value="50" />
<property name="concurrentConsumers" value="1" />
<property name="receiveTimeout" value="5000" />
<property name="recoveryInterval" value="60000" />
<property name="autoStartup" value="false" />
</bean>
<int:channel id="TRANSLATED-MSG-CHANNEL"/>
<bean id="TRANSLATED-MDCAD" class="com.ibm.mq.jms.MQQueue">
<constructor-arg value="TRANSLATED-MESSAGE-QUEUE" />
</bean>
<int-jms:message-driven-channel-adapter
id="MDB-TRANSLATED"
channel="TRANSLATED-MSG-CHANNEL" container="translatorContainer" acknowledge="transacted"/>
<int:service-activator input-channel="IN-MSG-CHANNEL"
output-channel="TRANSLATED-MSG-CHANNEL" ref="myProcess"
method="execute" />
但是在myProcess(ServiceActivator)中的RuntimeException上,我在日志中看到了以下内容
WARN : [2014-03-16 00:11:51.219] org.springframework.jms.listener.DefaultMessageListenerContainer - Execution of JMS message listener failed, and no ErrorHandler has been set.
org.springframework.integration.MessagingException: failed to handle incoming JMS Message
at org.springframework.integration.jms.SubscribableJmsChannel$DispatchingMessageListener.onMessage(SubscribableJmsChannel.java:164)
at org.springframework.jms.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:561)
at org.springframework.jms.listener.AbstractMessageListenerContainer.invokeListener(AbstractMessageListenerContainer.java:499)
at org.springframework.jms.listener.AbstractMessageListenerContainer.doExecuteListener(AbstractMessageListenerContainer.java:467)
at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.doReceiveAndExecute(AbstractPollingMessageListenerContainer.java:325)
at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.receiveAndExecute(AbstractPollingMessageListenerContainer.java:263)
at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.invokeListener(DefaultMessageListenerContainer.java:1059)
at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.executeOngoingLoop(DefaultMessageListenerContainer.java:1051)
at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.run(DefaultMessageListenerContainer.java:948)
at java.lang.Thread.run(Thread.java:662)
我调试了DefaultMessageListenerContainer,JmsMessageDrivenEndpointParser和其他一些内部类,发现容器设置正确。
但是当抛出异常时,它使用默认容器(不是我在int-jms上设置的那个:message-driven-channel-adapter:translatorContainer,它设置了errorHandler)
可能是什么原因?是否有任何其他备用设置我可以尝试将运行时异常重定向到errorChannel?如果您需要更多信息,请告诉我
我使用的是Spring集成版本2.2.5
#### DETAIL CONFIG<?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:context="http://www.springframework.org/schema/context"
xmlns:int-jms="http://www.springframework.org/schema/integration/jms"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/integration/jms http://www.springframework.org/schema/integration/jms/spring-integration-jms.xsd
">
<bean id="connectionFactory" class="com.ibm.mq.jms.MQQueueConnectionFactory">
<property name="hostName">
<value>${mq_hostname}</value>
</property>
<property name="port">
<value>${mq_port}</value>
</property>
<property name="queueManager">
<value>${mq_queuemanager}</value>
</property>
<property name="channel">
<value>${mq_channel}</value>
</property>
<property name="transportType" value="1" />
<property name="useConnectionPooling">
<value>true</value>
</property>
</bean>
<int:annotation-config />
<int:message-history />
<bean id="defaultMessageListenerContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="destination" ref="DEBATCHED-MDCAD" />
<property name="connectionFactory" ref="connectionFactory" />
<property name="errorHandler" ref="manifestErrorHandler"/>
<property name="sessionTransacted" value="true" />
<property name="maxConcurrentConsumers" value="50" />
<property name="concurrentConsumers" value="1" />
<property name="receiveTimeout" value="5000" />
<property name="recoveryInterval" value="60000" />
<property name="autoStartup" value="false" />
</bean>
</bean>
<bean id="translatorContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="destination" ref="TRANSLATED-MDCAD" />
<property name="connectionFactory" ref="connectionFactory" />
<property name="errorHandler" ref="manifestErrorHandler"/>
<property name="sessionTransacted" value="true" />
<property name="maxConcurrentConsumers" value="50" />
<property name="concurrentConsumers" value="1" />
<property name="receiveTimeout" value="5000" />
<property name="recoveryInterval" value="60000" />
<property name="autoStartup" value="false" />
</bean>
</bean>
<!-- Global Channel Interceptor -->
<int:channel-interceptor ref="metadataInterceptor"
pattern="*CHANNEL" order="1" />
<int:wire-tap pattern="*CHANNEL" order="1" channel="logger" />
<int:gateway id="manifestGateway"
service-interface="gov.dhs.cbp.manifest.oceanexport.gateway.ManifestGateway" error-channel="ERRORS-MSG-CHANNEL" />
<int:logging-channel-adapter id="logger"
level="ERROR" log-full-message="true" />
<int-jms:channel id="INBOUND-MSG-CHANNEL" queue-name="INBOUND" error-handler="manifestErrorHandler"/>
<int:channel id="DEBATCHED-MSG-CHANNEL" />
<bean id="DEBATCHED-MDCAD" class="com.ibm.mq.jms.MQQueue">
<constructor-arg value="DEBATCHED" />
</bean>
<int-jms:message-driven-channel-adapter
id="MDB-DEBATCHED"
channel="DEBATCHED-MSG-CHANNEL" container="defaultMessageListenerContainer" acknowledge="transacted"/>
<bean id="manifestErrorHandler" class="gov.dhs.cbp.manifest.process.util.ManifestErrorHandler"/>
<int:channel id="TRANSLATED-MSG-CHANNEL"/>
<bean id="TRANSLATED-MDCAD" class="com.ibm.mq.jms.MQQueue">
<constructor-arg value="TRANSLATED" />
</bean>
<int-jms:message-driven-channel-adapter
id="MDB-TRANSLATED"
channel="TRANSLATED-MSG-CHANNEL" container="translatorContainer" acknowledge="transacted"/>
<int:channel id="ERRORS-MSG-CHANNEL" />
<bean id="ERROR-EXTERNAL" class="com.ibm.mq.jms.MQQueue">
<constructor-arg value="ERRORS" />
</bean>
<int-jms:outbound-channel-adapter id="ERROR-EXTERNAL-ADAPTER"
channel="ERRORS-MSG-CHANNEL" destination="ERROR-EXTERNAL" />
<int-jms:outbound-channel-adapter id="ERROR-CHANNEL-EXTERNAL-ADAPTER"
channel="errorChannel" destination="ERROR-EXTERNAL" />
<!-- ## Service Activator ## -->
<int:service-activator input-channel="DEBATCHED-MSG-CHANNEL"
output-channel="TRANSLATED-MSG-CHANNEL" ref="manifestProcess"
method="execute" />
<!-- DEBATCHER - SPLITTER -->
<int:splitter input-channel="INBOUND-MSG-CHANNEL"
output-channel="DEBATCHED-MSG-CHANNEL" ref="debatcherService"
method="execute" />
<!-- RESPONSE SERVICE / NOT ROUTER DUE TO BUSINESS LOGIC -->
<int:service-activator input-channel="TRANSLATED-MSG-CHANNEL" ref="responseService"
method="generateResponse"/>
<bean id="pool"
class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
<property name="corePoolSize" value="8" />
</bean>
<!--
<bean id="retryTemplate" class="org.springframework.retry.support.RetryTemplate">
<property name="retryPolicy">
<bean class="org.springframework.retry.policy.SimpleRetryPolicy">
<property name="maxAttempts" value="4" />
</bean>
</property>
<property name="backOffPolicy">
<bean class="org.springframework.retry.backoff.ExponentialBackOffPolicy">
<property name="initialInterval" <value="1000" />
<property name="multiplier" value="5" />
</bean>
</property>
</bean>
-->
</beans>
<bean id="retryTemplate" class="org.springframework.retry.support.RetryTemplate">
<property name="retryPolicy">
<bean class="org.springframework.retry.policy.SimpleRetryPolicy">
<property name="maxAttempts" value="1" />
</bean>
</property>
<property name="backOffPolicy">
<bean class="org.springframework.retry.backoff.ExponentialBackOffPolicy">
<property name="initialInterval" value="1000" />
<property name="multiplier" value="5" />
</bean>
</property>
</bean>
<int:service-activator input-channel="DEBATCHED-MSG-CHANNEL"
output-channel="TRANSLATED-MSG-CHANNEL" ref="manifestProcess"
method="execute" >
<int:request-handler-advice-chain>
<bean class="org.springframework.integration.handler.advice.RequestHandlerRetryAdvice">
<property name="recoveryCallback">
<bean class="org.springframework.integration.handler.advice.ErrorMessageSendingRecoverer">
<constructor-arg ref="errorChannel" />
</bean>
</property>
<property name="retryTemplate" ref="retryTemplate" />
</bean>
</int:request-handler-advice-chain>
</int:service-activator>
答案 0 :(得分:2)
正如我们在StackTrace中看到的那样,问题出在SubscribableJmsChannel
(<int-jms:channel id="fooChannel" queue-name="foo"/>
),您不使用自定义container
。
但是您显示了<int-jms:message-driven-channel-adapter>
的配置。
所以,小心分析问题。
现在,如果您希望<int-jms:channel/>
采用相同的行为,则可以将myErrorHandler
注入频道的媒体资源error-handler