2017-04-03 2 views
2

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 von Messages.direct()
  • Wrapping die ActiveMQConnectionFactory in einem CachingConnectionFactory

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?

Antwort

1

Ugh! Das ist definitiv ein Fehler. Und es sieht so aus, als ob du es richtig umgehst.

Obwohl in Betracht ziehen, alle DisposableBean dort zu zerstören.

Ich füge das Update der Spring Integration Java DSL. Wir werden die nächste 1.2.2 kurz nach der Frühlingsintegration 4.3.9 veröffentlichen.

Die Frühlingsintegration 5.0 wird morgen in ihrem M3 Release behoben werden.

Verwandte Themen