【问题标题】:JmsTemplate cannot send response because javax.jms.IllegalStateException: Session is closedJmsTemplate 无法发送响应,因为 javax.jms.IllegalStateException:会话已关闭
【发布时间】:2018-11-15 03:53:42
【问题描述】:

我有一个使用 Spring 连接到 TIBCO(队列)的独立应用程序。有时,由于各种原因,TIBCO 连接被服务器关闭。大部分事情正在从中恢复。但是,由于以下错误,有时 JmsTemplate 无法发送响应。我有一个重试,但同样的错误不断出现(见下面的跟踪)。

可能很重要的细节:

我正在使用 DefaultMessageListenerContainer 来获取请求并在该接收线程中发送响应。另外,我对 DefaultMessageListenerContainer 和 JmsTemplate 使用相同的连接工厂。

Caused by: org.springframework.jms.IllegalStateException: Session is closed; nested exception is javax.jms.IllegalStateException: Session is closed
        at org.springframework.jms.support.JmsUtils.convertJmsAccessException(JmsUtils.java:279)
        at org.springframework.jms.support.JmsAccessor.convertJmsAccessException(JmsAccessor.java:169)
        at org.springframework.jms.core.JmsTemplate.execute(JmsTemplate.java:487)
        at org.springframework.jms.core.JmsTemplate.send(JmsTemplate.java:559)
        at org.springframework.jms.core.JmsTemplate.convertAndSend(JmsTemplate.java:682)
        at org.springframework.jms.core.JmsTemplate.convertAndSend(JmsTemplate.java:670)
        at org.springframework.integration.jms.JmsSendingMessageHandler.send(JmsSendingMessageHandler.java:149)
        at org.springframework.integration.jms.JmsSendingMessageHandler.handleMessageInternal(JmsSendingMessageHandler.java:116)
        at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:127)
        ... 83 more
Caused by: javax.jms.IllegalStateException: Session is closed
        at com.tibco.tibjms.TibjmsxSessionImp._createProducer(TibjmsxSessionImp.java:1067)
        at com.tibco.tibjms.TibjmsxSessionImp.createProducer(TibjmsxSessionImp.java:5080)
        at org.springframework.jms.core.JmsTemplate.doCreateProducer(JmsTemplate.java:1114)
        at org.springframework.jms.core.JmsTemplate.createProducer(JmsTemplate.java:1095)
        at org.springframework.jms.core.JmsTemplate.doSend(JmsTemplate.java:591)
        at org.springframework.jms.core.JmsTemplate$3.doInJms(JmsTemplate.java:562)
        at org.springframework.jms.core.JmsTemplate.execute(JmsTemplate.java:484)
        ... 89 more

与 TIBCO 队列的通信是使用 Spring 框架完成的。这是配置。 DefaultMessageListenerContainer 接收到一条消息,对其进行处理并使用 JmsTemplate 发回响应。连接工厂在接收方和发送方之间共享(这可能是个问题吗?)。

    <bean id="connectionFactory"
            class="org.springframework.jms.connection.SingleConnectionFactory">
            <constructor-arg ref="tibcoJNDI" />
            <property name="targetConnectionFactory">
                    <bean class="org.springframework.jndi.JndiObjectFactoryBean">
                            <property name="jndiTemplate" ref="tibcoJNDI"/>
                            <property name="jndiName" value="${tibco.queueConnectionFactory}" />
                    </bean>
            </property>
            <property name="reconnectOnException" value="true"/>

    </bean>

<bean id="client.req.msg.lstnr" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
    <property name="autoStartup" value="false"/>
    <property name="connectionFactory" ref="connectionFactory"/>
    <property name="destination" ref="ext_client.request.queue"/>
    <property name="sessionAcknowledgeMode" value="3"/>
    <property name="concurrentConsumers" value="6"/>
    <property name="receiveTimeout" value="60000"/>
</bean>

<jms:outbound-channel-adapter
    jms-template="ext.outbound.jms.template"
    channel="jms.to.ext.clnt.reply"/>

<bean id="ext.outbound.jms.template" class="org.springframework.jms.core.JmsTemplate">
    <property name="connectionFactory" ref="connectionFactory"/>
    <property name="defaultDestination" ref="ext_client.reply.queue"/>
    <property name="timeToLive" value="10800000" />
    <property name="explicitQosEnabled" value="true" />
</bean>

更多细节可能会有所帮助。我只是注意到第一个例外实际上是不同的。首先有一个“连接已关闭”异常,然后是多个“会话已关闭”异常(重试时)。

Caused by: javax.jms.JMSException: Connection is closed
    at com.tibco.tibjms.TibjmsxLink.sendRequest(TibjmsxLink.java:322)
    at com.tibco.tibjms.TibjmsxLink.sendRequest(TibjmsxLink.java:286)
    at com.tibco.tibjms.TibjmsxLink.sendRequestMsg(TibjmsxLink.java:261)
    at com.tibco.tibjms.TibjmsxSessionImp._createProducer(TibjmsxSessionImp.java:1075)
    at com.tibco.tibjms.TibjmsxSessionImp.createProducer(TibjmsxSessionImp.java:5080)
    at org.springframework.jms.core.JmsTemplate.doCreateProducer(JmsTemplate.java:1114)
    at org.springframework.jms.core.JmsTemplate.createProducer(JmsTemplate.java:1095)
    at org.springframework.jms.core.JmsTemplate.doSend(JmsTemplate.java:591)
    at org.springframework.jms.core.JmsTemplate$3.doInJms(JmsTemplate.java:562)
    at org.springframework.jms.core.JmsTemplate.execute(JmsTemplate.java:484)
    ... 89 more

【问题讨论】:

  • 请分享导致问题的代码,以便我们帮助诊断错误。谢谢!
  • 嗨 CD,以后请使用任何代码编辑您的帖子,而不是放在评论中,这样更容易阅读!
  • 信息已添加到帖子中。

标签: java spring connection tibco


【解决方案1】:

Spring 似乎没有正确处理这种情况。我通过覆盖 JmsTemplate(下面的代码)并自己处理异常(清理会话和连接)解决了这个问题。我希望这会有所帮助。

public <T> T execute(SessionCallback<T> action, boolean startConnection) throws JmsException {
    try {
        return super.execute(action, startConnection);
    } catch (JmsException jmse) {
        logger.error("Exception while executing in JmsTemplate (will cleanup session & connection): ", jmse);
        Object resourceHolder =
                TransactionSynchronizationManager.getResource(getConnectionFactory());
        if (resourceHolder != null && resourceHolder instanceof JmsResourceHolder) {
            ((JmsResourceHolder)resourceHolder).closeAll();
        }

        throw jmse;
    }
}

【讨论】:

    【解决方案2】:

    这个答案可能对https://stackoverflow.com/a/24494739/208934 有帮助,尤其是:

    使用 JMS 时,您不应该真正缓存 JMS 会话(以及 任何挂在上面的东西,比如制片人)。原因在于 JMS 会话是 JMS 中的工作单元,因此应该是 短命的对象。在 Java EE 世界中,JMS Session 也可能 例如,被纳入全球事务,因此需要 范围正确。

    听起来您正在为多个操作重用同一个会话。

    我在一些测试中看到了这个问题,告诉 Spring 使用连接池通常可以解决这个问题。如果您使用的是 active-mq,那么可以使用属性 spring.activemq.pooled=true 来完成。我不是 100% Tibco 如何完成同样的事情。

    通过定义将覆盖默认值的PooledConnectionFactory bean,您可能会得到相同的结果。

    【讨论】:

      猜你喜欢
      • 2016-02-19
      • 2013-04-27
      • 1970-01-01
      • 2012-10-19
      • 1970-01-01
      • 2014-07-19
      • 2013-05-15
      • 2010-10-28
      • 1970-01-01
      相关资源
      最近更新 更多