Java JMS入站网关-无法发送回复目标队列时的错误处理

Java JMS入站网关-无法发送回复目标队列时的错误处理,java,spring,spring-integration,spring-jms,Java,Spring,Spring Integration,Spring Jms,我们有一个EIP流,它使用基于注释的spring:4.2.xAPI、spring集成:4.2.xAPI和spring集成java dsl:1.1.0API从Websphere MQ队列接收消息,进行一些处理,最后将响应返回到另一个Websphere MQ队列。对于这个流,我们使用JMS入站网关从一个队列同步接收消息,处理它们并将响应发送回另一个队列 JMS入站网关配置了一个errorChannel,以便将RuntimeExceptions路由到它(这可以正常工作)。但是,在测试期间,当我们有意对

我们有一个EIP流,它使用基于注释的
spring:4.2.x
API、
spring集成:4.2.x
API和
spring集成java dsl:1.1.0
API从Websphere MQ队列接收消息,进行一些处理,最后将响应返回到另一个Websphere MQ队列。对于这个流,我们使用
JMS入站网关
从一个队列同步接收消息,处理它们并将响应发送回另一个队列

JMS入站网关
配置了一个
errorChannel
,以便将
RuntimeException
s路由到它(这可以正常工作)。但是,在测试期间,当我们有意对流的响应Websphere MQ队列应用PUT_INHIBIT(即,导致流无法将响应发送回应答队列)时,spring日志显示以下
警告
日志消息:

警告…-执行JMS消息侦听器失败,未设置ErrorHandler。
javax.jms.JMSException:MQJMS2007:未能将消息发送到MQ队列。

我们知道我们可以通过在
MLC
本身上配置
ErrorHandler
来删除
警告
日志,但是,这会给我们带来问题的原因是,当我们回传响应时,我们实际上使用
.routeToRecipients()
调用
.setIgnoreFailures(false)进行路由
和两个接收者-第一个接收者路由到
JMS入站网关
replyChannel
,第二个路由到发送后流,以便我们可以进行数据库更新等。这里的想法是,如果第一个接收者发送失败(即,当响应队列不可用时),发送后流程不执行,而是执行错误处理流程(例如
errorChannel
flow)。但是在所描述的错误场景中,我们看到警告日志,流的发送后流仍然执行,而不是
errorChannel
的流

此时,似乎
JMS入站网关
errorChannel
不再适用。这是正确的吗?这是故意的行为吗?如果是,这是否意味着我们应该使用
入站/出站适配器
s而不是
入站网关
来实现发送后的响应意图

JMS MLC配置:

@Bean( destroyMethod = "shutdown")
public DefaultMessageListenerContainer serviceMLC() throws Exception {

    DefaultMessageListenerContainer mlc = new DefaultMessageListenerContainer();
    mlc.setAutoStartup(false);
    mlc.setConnectionFactory(serviceCCF);
    mlc.setDestination(requestMqQueue);
    mlc.setAcceptMessagesWhileStopping(false);
    return mlc;
}
@Bean
public IntegrationFlow serviceFlow() {

    return IntegrationFlows
            .from(Jms
                    .inboundGateway(serviceMLC)
                    .autoStartup(true)
                    .defaultReplyDestination(responseMqQueue)
                    .replyChannel(responseOutCh)
                    .replyTimeout(180000)
                    .correlationKey("JMSCorrelationID")
                    .errorChannel(serviceErrorCh)
                    )
            .channel(serviceInCh)
            .get();
}
JMS入站网关配置:

@Bean( destroyMethod = "shutdown")
public DefaultMessageListenerContainer serviceMLC() throws Exception {

    DefaultMessageListenerContainer mlc = new DefaultMessageListenerContainer();
    mlc.setAutoStartup(false);
    mlc.setConnectionFactory(serviceCCF);
    mlc.setDestination(requestMqQueue);
    mlc.setAcceptMessagesWhileStopping(false);
    return mlc;
}
@Bean
public IntegrationFlow serviceFlow() {

    return IntegrationFlows
            .from(Jms
                    .inboundGateway(serviceMLC)
                    .autoStartup(true)
                    .defaultReplyDestination(responseMqQueue)
                    .replyChannel(responseOutCh)
                    .replyTimeout(180000)
                    .correlationKey("JMSCorrelationID")
                    .errorChannel(serviceErrorCh)
                    )
            .channel(serviceInCh)
            .get();
}

对,;网关不是那样工作的

当您向网关发送回复时,它将在网关中排队,直到线程返回网关;此时,将拾取并发送回复。因此,发送失败直到稍后才会发生(在调用第二个收件人流之后)


是的,要执行您想要的操作,您应该改用通道适配器,因为故障将直接在调用线程上运行。

您能指出一个使用Java类的示例吗?(不是bean-config-xml)您不应该在对(非常)旧的答案的评论中提出无关的问题。你问的问题也一点也不清楚——什么样的问题?问一个更清晰的新问题。这不是无关的。您接受的答案没有提供任何使用@Bean在Java中执行的示例链接,仅此而已,但它就在问题中(
@Bean
)。就像我说的,问一个更详细的新问题将有助于人们准确地理解你需要什么帮助。堆栈溢出不适用于扩展注释(管理员不鼓励这样做)。