システムがJMSメッセージを受信したときに、アプリケーションコンテキストを更新したいと思います。これを行うために、ApplicationContextAwareを実装するサービスアクティベーターにメッセージを転送するSpring Integration jms:message-driven-channel-adapterを設定しました。このアクティベータ(ConfigurationReloaderクラス)は、ConfigurableApplicationContext#refresh()メソッドを呼び出します。
以下はサンプルコードスニペットです。
<jms:message-driven-channel-adapter id="jmsDriverConfigurationAdapter"
destination="configurationApplyQueue" channel="jmsConfigurationInboundChannel" />
<channel id="jmsConfigurationInboundChannel"/>
<service-activator input-channel="jmsConfigurationInboundChannel" ref="configurationReloader" method="refresh"/>
そして私のアクティベーター:
public final class ConfigurationReloader implements ApplicationContextAware {
private ConfigurableApplicationContext applicationContext;
public void refresh() {
this.applicationContext.refresh();
}
@Override
public void setApplicationContext(
final ApplicationContext applicationContext) throws BeansException {
if (applicationContext instanceof ConfigurableApplicationContext) {
this.applicationContext =
(ConfigurableApplicationContext) applicationContext;
}
}
}
このようなメッセージを配信する場合、コンテキストはシャットダウン操作を開始しますが、DefaultMessageListenerContainerBeanのシャットダウンでスタックします。
2011-11-14 15:42:52,980 [org.springframework.jms.listener.DefaultMessageLis tenerContainer#0-1] DEBUG org.springframework.jms.listener.DefaultMessageLis tenerContainer - Shutting down JMS listener container
2011-11-14 15:42:52,980 [org.springframework.jms.listener.DefaultMessageLis tenerContainer#0-1] DEBUG org.springframework.jms.listener.DefaultMessageLis tenerContainer - Waiting for shutdown of message listener invokers
2011-11-14 15:42:55,104 [org.springframework.jms.listener.DefaultMessageLis tenerContainer#0-1] DEBUG org.springframework.jms.listener.DefaultMessageLis tenerContainer - Still waiting for shutdown of 1 message listener invokers
新しい構成パラメーターがメッセージとともに配信されるため、JMSを介してこの操作を呼び出すことは私にとって非常に重要です。これは、最新のSpringCoreとSpring Integrationに基づいて、前面にDispatcherServletを備えた標準のSpringMVCアプリケーションです。また、コントローラーを介したConfigurationLoaderの呼び出しは正常に機能するため、JMS関連の問題であると確信しています。
デバッグしたところ、DefaultMessageListenerContainer#538行の呼び出し(lifecycleMonitorのwait()メソッド)の後でスタックします。
/**
* Destroy the registered JMS Sessions and associated MessageConsumers.
*/
protected void doShutdown() throws JMSException {
logger.debug("Waiting for shutdown of message listener invokers");
try {
synchronized (this.lifecycleMonitor) {
while (this.activeInvokerCount > 0) {
if (logger.isDebugEnabled()) {
logger.debug("Still waiting for shutdown of " + this.activeInvokerCount +
" message listener invokers");
}
this.lifecycleMonitor.wait(); // <--- line 538
}
}
}
catch (InterruptedException ex) {
// Re-interrupt current thread, to allow other threads to react.
Thread.currentThread().interrupt();
}
}
...モニターにnotify/notifyAllを呼び出す人がいないので、何らかのバグである可能性がありますか?
ヒントありがとうございます!