Ich habe ein Problem, bei dem versucht, Tomcat (8) ordnungsgemäß abzuschalten nie endet, aufgrund der scheinbar DefaultMessageListenerContainer
blockiert wird (oder Schleifen) auf unbestimmte Zeit.Tomcat hängt mit Spring Integration herunter Java DSL
Ich habe für Lösungen googlen, aber alles, was ich gefunden habe, hat nicht funktioniert. Dies umfasst (ist aber nicht beschränkt auf):
configureListenerContainer()
Verwenden des taskExecutor des Behälters- Verwendung
Messages.queue()
anstelle vonMessages.direct()
- Wrapping die
ActiveMQConnectionFactory
in einemCachingConnectionFactory
ein einfacher einzustellen Servlet 3.0 Beispiel:
compile 'org.springframework.integration:spring-integration-core:4.3.6.RELEASE'
compile 'org.springframework.integration:spring-integration-jms:4.3.6.RELEASE'
compile 'org.springframework.integration:spring-integration-java-dsl:1.2.1.RELEASE'
Initializer:
public class ExampleWebApp implements WebApplicationInitializer {
@Override
public void onStartup(final ServletContext servletContext) throws ServletException {
final AnnotationConfigWebApplicationContext springContext = new AnnotationConfigWebApplicationContext();
springContext.register(ExampleConfig.class);
servletContext.addListener(new ContextLoaderListener(springContext));
final ServletRegistration.Dynamic registration = servletContext.addServlet("example", new HttpRequestHandlerServlet());
registration.setLoadOnStartup(1);
registration.addMapping("/status");
}
}
Konfiguration:
@Configuration
@EnableIntegration
public class ExampleConfig {
@Bean
public ConnectionFactory connectionFactory() {
final ActiveMQConnectionFactory mqConnectionFactory = new ActiveMQConnectionFactory();
mqConnectionFactory.setBrokerURL("tcp://host:port");
mqConnectionFactory.setUserName("----");
mqConnectionFactory.setPassword("----");
return mqConnectionFactory;
}
@Bean
public Queue testQueue() {
return new ActiveMQQueue("test.queue");
}
@Bean
public MessageChannel testReceiveChannel() {
return MessageChannels.direct().get();
}
@Bean
public IntegrationFlow pushMessageInboundFlow() {
return IntegrationFlows
.from(Jms.messageDrivenChannelAdapter(connectionFactory())
.destination(testQueue()))
.log()
.transform(new JsonToObjectTransformer(TestMessageObject.class))
.channel(testReceiveChannel())
.get();
}
/** Example message object */
public static class TestMessageObject {
private String text;
public String getText() {
return text;
}
public void setText(final String text) {
this.text = text;
}
}
}
Wenn ich versuche, und diese (zum Beispiel über das catalina.sh Skript zu stoppen, "Stop" in IntelliJ“drücken, es nie beendet bestehend. Bisher ist der einzige Weg, ich in der Lage gewesen bin Abschaltung bis Ende zu bekommen, ist durch „manuell“ die Zerstörung den JmsMessageAdapters beim Herunterfahren, über eine kleine Hilfsklasse:
public class JmsMessageListenerContainerLifecycleManager {
private static final Logger LOG = LoggerFactory.getLogger(JmsMessageListenerContainerLifecycleManager.class);
@Autowired
private List<IntegrationFlow> mIntegrationFlows;
@PreDestroy
public void shutdownJmsAdapters() throws Exception {
LOG.info("Checking {} integration flows for JMS message adapters", mIntegrationFlows.size());
for (IntegrationFlow flow : mIntegrationFlows) {
if (flow instanceof StandardIntegrationFlow) {
final StandardIntegrationFlow standardFlow = (StandardIntegrationFlow) flow;
for (Object component : standardFlow.getIntegrationComponents()) {
if (component instanceof JmsMessageDrivenChannelAdapter) {
final JmsMessageDrivenChannelAdapter adapter = (JmsMessageDrivenChannelAdapter) component;
LOG.info("Destroying JMS adapter {}", adapter.getComponentName());
adapter.destroy();
}
}
}
}
}
}
Und während das funktioniert, es fühlt sich definitiv wie falsch Lösung.
Früher habe ich XML-Konfiguration der Feder-Integration verwendet, und ich hatte dieses Problem nicht. Was vermisse ich?