我使用 Spring JMS DefaultMessageListenerContainer 并在 Spring 的 init 方法上初始化队列,并在 destroy 方法上销毁 listnereContainer 。 但是,当我使用“./catalina.sh stop”命令关闭 tomcat 服务器时,在使用线程转储工具时出现以下异常:
"localhost-startStop-2" #155 daemon prio=5 os_prio=0 tid=0x00007fd4c0015800 nid=0x5265 in Object.wait() [0x00007fd4c4f60000] java.lang.Thread.State: WAITING (on object monitor) at java.lang.Object.wait(Native Method) - waiting on <0x00000007752ccae8> (a java.lang.Object) at java.lang.Object.wait(Object.java:502) at org.springframework.jms.listener.DefaultMessageListenerContainer.doShutdown(DefaultMessageListenerContainer.java:545) - locked <0x00000007752ccae8> (a java.lang.Object) at org.springframework.jms.listener.AbstractJmsListeningContainer.shutdown(AbstractJmsListeningContainer.java:237) at org.springframework.jms.listener.AbstractJmsListeningContainer.destroy(AbstractJmsListeningContainer.java:177) at com.bng.ocg.queue.QueueConnection.destroy(QueueConnection.java:71) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
以下是 init 和 destroy 方法:
public void init() {
try {
connection = pooledConnectionFactory.createConnection();
session = connection.createSession(false,
Session.DUPS_OK_ACKNOWLEDGE);
updateDefaultQueue();
updateDefaultConsumer();
} catch (JMSException e) {
Logger.sysLog(LogValues.error, this.getClass().getName(), coreException.GetStack(e));
} catch (Exception e) {
Logger.sysLog(LogValues.error, this.getClass().getName(), coreException.GetStack(e));
}
}
public void destroy(){
for(DefaultMessageListenerContainer defaultMessageListenerContainer : defaultMessageListenerContainersCdrQueue)
defaultMessageListenerContainer.destroy();
for(DefaultMessageListenerContainer defaultMessageListenerContainer : defaultMessageListenerContainersDataSyncMsgQueue)
defaultMessageListenerContainer.destroy();
for(DefaultMessageListenerContainer defaultMessageListenerContainer : defaultMessageListenerContainersUrlHitterMsgQueue)
defaultMessageListenerContainer.destroy();
try {
session.close();
} catch (JMSException e) {
Logger.sysLog(LogValues.error, this.getClass().getName(), coreException.GetStack(e));
}
try {
connection.close();
} catch (JMSException e) {
Logger.sysLog(LogValues.error, this.getClass().getName(), coreException.GetStack(e));
}
pooledConnectionFactory.clear();
}
private void updateDefaultQueue() {
for (int i = 0; i < cdrQueueInitialLength; i++) {
cdrQueueList.add(cdrQueueNamePrefixString + i);
}
for (int i = 0; i < dataSyncMsgQueueInitialLength; i++) {
dataSyncMsgQueueList.add(dataSyncMsgQueueNamePrefixString + i);
}
for (int i = 0; i < urlHitterMsgQueueInitialLength; i++) {
urlHitterMsgQueueList.add(urlHitterMsgQueueNamePrefixString + i);
}
}
private void updateDefaultConsumer() throws JMSException
{
/*for (int i = 0; i < cdrQueueInitialLength; i++) {
defaultMessageListenerContainer = defaultMessageListenerContainerFactory
.getObject();
defaultMessageListenerContainer.setDestination(session
.createQueue(cdrQueueList.get(i)));
defaultMessageListenerContainer
.setMessageListener(cdrMessageListener);
defaultMessageListenerContainer.start();
defaultMessageListenerContainersCdrQueue
.add(defaultMessageListenerContainer);
}*/
for (int i = 0; i < dataSyncMsgQueueInitialLength; i++) {
defaultMessageListenerContainer = defaultMessageListenerContainerDataSyncFactory
.getObject();
defaultMessageListenerContainer.setDestination(session
.createQueue(dataSyncMsgQueueList.get(i)));
defaultMessageListenerContainer
.setMessageListener(dataSyncMsgListener);
defaultMessageListenerContainer.start();
defaultMessageListenerContainersDataSyncMsgQueue
.add(defaultMessageListenerContainer);
}
for (int i = 0; i < urlHitterMsgQueueInitialLength; i++) {
defaultMessageListenerContainer = defaultMessageListenerContainerUrlHitterFactory
.getObject();
defaultMessageListenerContainer.setDestination(session
.createQueue(urlHitterMsgQueueList.get(i)));
defaultMessageListenerContainer
.setMessageListener(urlHitterMsgListener);
defaultMessageListenerContainer.start();
defaultMessageListenerContainersUrlHitterMsgQueue
.add(defaultMessageListenerContainer);
}
}
有什么建议可以解决这个问题吗?
最佳答案
我认为你的destroy()
没有被调用??
您必须将@PreDestroy
添加到您的destroy()
方法中或使用spring @EventListener
或实现ApplicationListener
@EventListener({ ContextClosedEvent.class })
public void destroy() {
}
@Component
public class ContextClosed implements ApplicationListener<ContextClosedEvent> {
@Override
public void onApplicationEvent(final ContextClosedEvent event) {
destroy(); // your destroy
}
}
关于java - Spring-ActiveMQ : DefaultMessageListenerContainer not getting destroyed,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44263208/