Java WeakReferences=理解问题(使用HornetQ JMS实现)?

Java WeakReferences=理解问题(使用HornetQ JMS实现)?,java,jms,weak-references,hornetq,Java,Jms,Weak References,Hornetq,以下代码不起作用: 原因: public class JMSMessageSenderTest { private static final Logger logger = Logger.getLogger(JMSMessageSenderTest.class); private static JMSMessageSenderTest instance; private Connection connection = null; private Session

以下代码不起作用:

原因:

public class JMSMessageSenderTest {
    private static final Logger logger = Logger.getLogger(JMSMessageSenderTest.class);

    private static JMSMessageSenderTest instance;

    private Connection connection = null;
    private Session session = null;
    private MessageProducer producer = null;

    private JMSMessageSenderTest() {
        super();
    }


    public static JMSMessageSenderTest getInstance() throws JMSException {
        if (instance==null) {
            synchronized(JMSMessageSenderTest.class) {
                if (instance==null) {
                    JMSMessageSenderTest instanceTmp = new JMSMessageSenderTest();
                    instanceTmp.initializeJMSConnectionFactory();
                    instance = instanceTmp;
                }
    } }
        return instance;
    }


    private void createConnectionSessionQueueProducer() throws Exception {

        try {


            Queue queue = HornetQJMSClient.createQueue("testQueue");

            connection = initializeJMSConnectionFactory();

             session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);

             producer = session.createProducer(queue);

             connection.start();

        } catch (Exception e) { 
            cleanupAfterError();
            throw e;
        }

    }


    private void cleanupAfterError() {

        if (connection != null){
             try{
                 connection.close();
             }catch(JMSException jmse) {
                 logger.error("Closing JMS Connection Failed",jmse);
             }
         }
    session = null;
    producer = null;

    }


    public synchronized void sendRequest(String url) throws Exception {

            if (connection==null) {
                createConnectionSessionQueueProducer();
            }

        try {

             //HERE THE EXCEPTION IS THROWN, at least when debugging
             TextMessage textMessage = session.createTextMessage(url);

             producer.send(textMessage); 

            } catch (Exception e) {
            cleanupAfterError();
            throw e;
        }

    }

        private Connection initializeJMSConnectionFactory() throws JMSException{

        Configuration configuration = ConfigurationFactory.getConfiguration(null, null);

        Map<String, Object> connectionParams = new HashMap<String, Object>();

        connectionParams.put(org.hornetq.core.remoting.impl.netty.TransportConstants.PORT_PROP_NAME, 5445);
        connectionParams.put(org.hornetq.core.remoting.impl.netty.TransportConstants.HOST_PROP_NAME, "localhost");

        TransportConfiguration transportConfiguration = new TransportConfiguration(NettyConnectorFactory.class.getName(), connectionParams);

        ConnectionFactory connectionFactory = (ConnectionFactory) HornetQJMSClient.createConnectionFactoryWithoutHA(JMSFactoryType.CF, transportConfiguration);

    //      return  connectionFactory.createConnection(login, password);    
        return connectionFactory.createConnection();

    }


    /**
     * Orderly shutdown of all resources.
     */
    public void shutdown() {
        cleanupAfterError();
    }


}
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!
The JMS connection you didn't close was created here:
java.lang.Exception
    at org.hornetq.jms.client.HornetQConnection.<init>(HornetQConnection.java:152)
    at org.hornetq.jms.client.HornetQConnectionFactory.createConnectionInternal(HornetQConnectionFactory.java:662)
    at org.hornetq.jms.client.HornetQConnectionFactory.createConnection(HornetQConnectionFactory.java:121)
我想我找到了原因: =>这篇文章说HornetQ使用弱引用

我的问题: 为什么代码不运行?(我使用稍微不同的实现运行此代码,但代码吹扫会反复失败)。我唯一的猜测是 以下参考资料:

private Connection connection = null;
private Session session = null;
private MessageProducer producer = null;
是否不被视为强引用?(这导致了垃圾收集器移除对象的事实……但它们不是强引用吗

或者代码是否存在其他问题(如前所述,如果我将所有内容复制到一个方法中,代码运行良好。但如果我使用下面的单线程方法,代码将不起作用…)另一个假设是,它可能与ThreadLocal内容有关,但我只使用一个线程

代码不工作(精简):

public class JMSMessageSenderTest {
    private static final Logger logger = Logger.getLogger(JMSMessageSenderTest.class);

    private static JMSMessageSenderTest instance;

    private Connection connection = null;
    private Session session = null;
    private MessageProducer producer = null;

    private JMSMessageSenderTest() {
        super();
    }


    public static JMSMessageSenderTest getInstance() throws JMSException {
        if (instance==null) {
            synchronized(JMSMessageSenderTest.class) {
                if (instance==null) {
                    JMSMessageSenderTest instanceTmp = new JMSMessageSenderTest();
                    instanceTmp.initializeJMSConnectionFactory();
                    instance = instanceTmp;
                }
    } }
        return instance;
    }


    private void createConnectionSessionQueueProducer() throws Exception {

        try {


            Queue queue = HornetQJMSClient.createQueue("testQueue");

            connection = initializeJMSConnectionFactory();

             session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);

             producer = session.createProducer(queue);

             connection.start();

        } catch (Exception e) { 
            cleanupAfterError();
            throw e;
        }

    }


    private void cleanupAfterError() {

        if (connection != null){
             try{
                 connection.close();
             }catch(JMSException jmse) {
                 logger.error("Closing JMS Connection Failed",jmse);
             }
         }
    session = null;
    producer = null;

    }


    public synchronized void sendRequest(String url) throws Exception {

            if (connection==null) {
                createConnectionSessionQueueProducer();
            }

        try {

             //HERE THE EXCEPTION IS THROWN, at least when debugging
             TextMessage textMessage = session.createTextMessage(url);

             producer.send(textMessage); 

            } catch (Exception e) {
            cleanupAfterError();
            throw e;
        }

    }

        private Connection initializeJMSConnectionFactory() throws JMSException{

        Configuration configuration = ConfigurationFactory.getConfiguration(null, null);

        Map<String, Object> connectionParams = new HashMap<String, Object>();

        connectionParams.put(org.hornetq.core.remoting.impl.netty.TransportConstants.PORT_PROP_NAME, 5445);
        connectionParams.put(org.hornetq.core.remoting.impl.netty.TransportConstants.HOST_PROP_NAME, "localhost");

        TransportConfiguration transportConfiguration = new TransportConfiguration(NettyConnectorFactory.class.getName(), connectionParams);

        ConnectionFactory connectionFactory = (ConnectionFactory) HornetQJMSClient.createConnectionFactoryWithoutHA(JMSFactoryType.CF, transportConfiguration);

    //      return  connectionFactory.createConnection(login, password);    
        return connectionFactory.createConnection();

    }


    /**
     * Orderly shutdown of all resources.
     */
    public void shutdown() {
        cleanupAfterError();
    }


}
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!
The JMS connection you didn't close was created here:
java.lang.Exception
    at org.hornetq.jms.client.HornetQConnection.<init>(HornetQConnection.java:152)
    at org.hornetq.jms.client.HornetQConnectionFactory.createConnectionInternal(HornetQConnectionFactory.java:662)
    at org.hornetq.jms.client.HornetQConnectionFactory.createConnection(HornetQConnectionFactory.java:121)
给出以下错误:

public class JMSMessageSenderTest {
    private static final Logger logger = Logger.getLogger(JMSMessageSenderTest.class);

    private static JMSMessageSenderTest instance;

    private Connection connection = null;
    private Session session = null;
    private MessageProducer producer = null;

    private JMSMessageSenderTest() {
        super();
    }


    public static JMSMessageSenderTest getInstance() throws JMSException {
        if (instance==null) {
            synchronized(JMSMessageSenderTest.class) {
                if (instance==null) {
                    JMSMessageSenderTest instanceTmp = new JMSMessageSenderTest();
                    instanceTmp.initializeJMSConnectionFactory();
                    instance = instanceTmp;
                }
    } }
        return instance;
    }


    private void createConnectionSessionQueueProducer() throws Exception {

        try {


            Queue queue = HornetQJMSClient.createQueue("testQueue");

            connection = initializeJMSConnectionFactory();

             session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);

             producer = session.createProducer(queue);

             connection.start();

        } catch (Exception e) { 
            cleanupAfterError();
            throw e;
        }

    }


    private void cleanupAfterError() {

        if (connection != null){
             try{
                 connection.close();
             }catch(JMSException jmse) {
                 logger.error("Closing JMS Connection Failed",jmse);
             }
         }
    session = null;
    producer = null;

    }


    public synchronized void sendRequest(String url) throws Exception {

            if (connection==null) {
                createConnectionSessionQueueProducer();
            }

        try {

             //HERE THE EXCEPTION IS THROWN, at least when debugging
             TextMessage textMessage = session.createTextMessage(url);

             producer.send(textMessage); 

            } catch (Exception e) {
            cleanupAfterError();
            throw e;
        }

    }

        private Connection initializeJMSConnectionFactory() throws JMSException{

        Configuration configuration = ConfigurationFactory.getConfiguration(null, null);

        Map<String, Object> connectionParams = new HashMap<String, Object>();

        connectionParams.put(org.hornetq.core.remoting.impl.netty.TransportConstants.PORT_PROP_NAME, 5445);
        connectionParams.put(org.hornetq.core.remoting.impl.netty.TransportConstants.HOST_PROP_NAME, "localhost");

        TransportConfiguration transportConfiguration = new TransportConfiguration(NettyConnectorFactory.class.getName(), connectionParams);

        ConnectionFactory connectionFactory = (ConnectionFactory) HornetQJMSClient.createConnectionFactoryWithoutHA(JMSFactoryType.CF, transportConfiguration);

    //      return  connectionFactory.createConnection(login, password);    
        return connectionFactory.createConnection();

    }


    /**
     * Orderly shutdown of all resources.
     */
    public void shutdown() {
        cleanupAfterError();
    }


}
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!
The JMS connection you didn't close was created here:
java.lang.Exception
    at org.hornetq.jms.client.HornetQConnection.<init>(HornetQConnection.java:152)
    at org.hornetq.jms.client.HornetQConnectionFactory.createConnectionInternal(HornetQConnectionFactory.java:662)
    at org.hornetq.jms.client.HornetQConnectionFactory.createConnection(HornetQConnectionFactory.java:121)
2.)并且此代码包含一个严重的隐藏bug(不太容易发现): 我在构造函数以及createConnectionSessionQueueProducer()方法中初始化了连接。因此,它将覆盖旧值,并且(因为它是一个需要关闭的Ressource)将导致一个陈旧的连接,HornetQ将关闭该连接,然后抛出错误


非常感谢!马库斯

我也有类似的问题。但它不应该崩溃。您的实现看起来不错。但唯一的问题是您没有关闭JMS连接,而这反过来又会被HornetQGC关闭

这段代码可能有一个错误,那就是只有在出现异常后才调用cleanupAfterError()。在发布消息并且JMS连接处于空闲状态后,也应该调用相同的方法。由于您只是打开一个连接来发布消息,然后除非发生异常,否则不会关闭该连接,所以Hornetq GC正在查找该对象并在抛出此错误时将其删除


如果我遗漏了什么,请告诉我。

释放连接工厂后,HornetQ将关闭连接工厂


您需要持有连接工厂的参考资料。

首先非常感谢您的回答!!!理论上你是对的,连接还没有关闭(使用这个实现)。这是我必须做的事。但这与我的上述问题无关:因为我甚至连一条信息都发不出去!我在(!)发送第一条消息之前收到此错误。这意味着,HornetQ内部出现了一些问题,因为HornetQ内部必须以某种方式关闭连接/会话,然后才能发送第一条消息。并且在(!)发送我的第一条消息后关闭我必须执行的会话/连接。谢谢!这是一个很好的学习(我对java很陌生,还没有处理weakreference…)。实际上代码包含两个错误(我更新了上面的学习内容)谢谢!!!