我使用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(在对象监视器上) at java.lang.Object.wait(Native Method) - 等待< 0x00000007752ccae8> (一个java.lang.Object) 在java.lang.Object.wait(Object.java:502) 在org.springframework.jms.listener.DefaultMessageListenerContainer.doShutdown(DefaultMessageListenerContainer.java:545) - 已锁定< 0x00000007752ccae8> (一个java.lang.Object) 在org.springframework.jms.listener.AbstractJmsListeningContainer.shutdown(AbstractJmsListeningContainer.java:237) 在org.springframework.jms.listener.AbstractJmsListeningContainer.destroy(AbstractJmsListeningContainer.java:177) 在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);
}
}
有任何解决此问题的建议吗?
答案 0 :(得分:0)
我认为您的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
}
}