下面的代码不起作用:
原因:
我假设我找到了原因:http: //community.jboss.org/thread/150988 =>这篇文章说 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();
}
}
TestCode 运行上面的代码
JMSMessageSenderTest jmsMessageSender = JMSMessageSenderTest.getInstance();
jmsMessageSender.sendRequest("www.example.com)");
jmsMessageSender.shutdown();
给出以下错误:
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)
解决方案:
1.)您还必须保留对 ConnectionFactory 的引用(请参阅下面 Clebert 的答案)
private ConnectionFactory factory = null;
2.)并且这段代码包含一个严重的隐藏错误(不是那么容易发现):我在构造函数和 createConnectionSessionQueueProducer() 方法中初始化了连接。因此它将覆盖旧值并且(因为它是一个需要关闭的资源)将导致一个陈旧的连接,然后 HornetQ 将关闭并抛出错误。
非常非常感谢!马库斯