升级后我们遇到两个问题:

1.)Spring 3.1到4.1.5.BUILD-SNAPSHOT

2.)JBoss Messaging Service 5.1.2到HornetQ-2.4.5.Final

问题是:

  • CachingConnectionFactory在HornetQ服务器出现故障并重新启动时没有重新刷新连接和陈旧的会话(例如,我每次发送都会得到"Session is closed"错误)

  • JmsTemplate(在非缓存CF中)不会关闭JMS连接

我们在旧平台上使用CachingConnectionFactory和JmsTemplate多年来一直是完美的 .

升级后,我现在丢失了我的CachingConnectionFactory和我的JmsTemplate!那么几个问题:

Is JmsTemplate only good inside a JTA transaction, so it can use the TxnSync facility to track the Jms Resources?

Is there a bug in HornetQ & Spring CachingConnectionFactory I need to workaround somehow?

I send several messages to different Destinations, outside of a JTA transaction. Is this not possible anymore?

2015-03-02 11:30:35,325 WARN  (Finalizer) [org.hornetq.jms.client] HQ122000: I''m closing a JMS connection you left open. Please make sure you close all JMS connections explicitly before letting them go out of scope! see stacktrace to find out where it was created
java.lang.Exception
    at org.hornetq.jms.client.HornetQConnection.<init>(HornetQConnection.java:151)
    at org.hornetq.jms.client.HornetQConnectionFactory.createConnectionInternal(HornetQConnectionFactory.java:722)
    at org.hornetq.jms.client.HornetQConnectionFactory.createConnection(HornetQConnectionFactory.java:112)
    at org.hornetq.jms.client.HornetQConnectionFactory.createConnection(HornetQConnectionFactory.java:107)
    at org.springframework.jms.support.JmsAccessor.createConnection(JmsAccessor.java:180)
    at org.springframework.jms.core.JmsTemplate.access$600(JmsTemplate.java:90)
    at org.springframework.jms.core.JmsTemplate$JmsTemplateResourceFactory.createConnection(JmsTemplate.java:1205)
    at org.springframework.jms.connection.ConnectionFactoryUtils.doGetTransactionalSession(ConnectionFactoryUtils.java:312)
    at org.springframework.jms.core.JmsTemplate.execute(JmsTemplate.java:480)
    at org.springframework.jms.core.JmsTemplate.send(JmsTemplate.java:568)
    at org.springframework.jms.core.JmsTemplate.convertAndSend(JmsTemplate.java:657)
    at org.springframework.jms.core.JmsTemplate.convertAndSend(JmsTemplate.java:648)

我的步骤是:

1.)createJMSMessage() - 使用JmsTemplate SessionCallback - 见下文 .

2.)填充JMS消息

3.)sendNow(Message) - 再次使用JmsTemplate

这是使用SessionCallback创建消息代码 .

public Message createJMSMessage(int messageType) {
    Message message = null;

    init();

    try {
        switch (messageType) {
            case JMS_MESSAGE_TYPE_OBJECT:
                message = (Message)jmsTemplate.execute(new SessionCallback<Object>() {
                    public Object doInJms(Session session) throws JMSException {
                        return session.createObjectMessage();
                    }
                }, false);
                //message = jmsProducer.createObjectMessage();
                break;

            default:
            .... Unknown type, log error here
        }

    } catch(Exception ex) {
        throw new SubSystemException("Failed to create message: "+ex.getMessage(), ex);
    }


return message;}

这是send()代码:

public void sendNow(Message message) {
        if (log.isDebugEnabled()) {
            log.debug("sendNow : Enter [" + destinationLocation+"]");
        }

        if (!JmsUtils.isPayloadNull(message)) {
            init();

            try {
                // Take properties from the Message and apply to our send()
                int priority = message.getJMSPriority();
                long expiration = message.getJMSExpiration();

                if (priority < 0) {
                    priority = Message.DEFAULT_PRIORITY;
                }   

                if (expiration < 0) {
                    expiration = Message.DEFAULT_TIME_TO_LIVE;
                }

                jmsTemplate.setPriority(priority);
                jmsTemplate.setTimeToLive(expiration);
                jmsTemplate.setPubSubDomain(isPubSub);  // false for Queues and true for Topics

                jmsTemplate.convertAndSend(message);
            } catch(JMSException ex) {
                throw new SubSystemException("sendNow() failed with JMSException. Details >>>> "+JmsUtils.toString(message), ex);
            }
        } else {
            if (log.isWarnEnabled()) {
                // Spring JMS listener container will puke on a null payload anyway, so
                // we just don't send it.  Spring JMS listener error is not descriptive enough
                // and at least here, we have more details on the message to log
                log.warn("sendNow : [" + destinationLocation+"] Payload is NULL.  "
                        + "Message not sent.  Details >>>> "+JmsUtils.toString(message));
            }
        }

        if (log.isDebugEnabled()) {
            log.debug("sendNow : Exit [" + destinationLocation+"]");
        }
    }