2016-09-21 1 views
1

Ich verwende CharacterStreamReadingMessageSource in einer Feder Integrationsfluss:CharacterStreamReadingMessageSource.stdin() und EOF

IntegrationFlows.from(CharacterStreamReadingMessageSource.stdin()) 

Es funktioniert. Das Problem ist, dass, wenn ich Rohr eine Datei auf den Prozess:

cat file | java -jar app.jar 

oder

java -jar app.jar < file 

sobald die Datei gelesen wurde, wird der EOF nicht propagiert, die stdin noch aktiv ist, und der Prozess Endet nicht. Gibt es etwas, was ich tun kann, damit es sich so verhält? Die manuelle Eingabe von ctrl-Z in der Befehlszeile funktioniert wie erwartet und schließt die Anwendung (Spring Boot App, kein Web).

Antwort

1

Leider wird es in diesem Szenario nicht funktionieren; Es wurde für die Konsoleneingabe entwickelt.

Die CharacterStreamReadingMessageSource wraps System.in in einem BufferedReader und verwendet readLine(). Da readLine() blockiert und wir einen Thread für lange Zeiträume nicht binden wollen, überprüfen wir reader.ready(), die false zurückgibt, wenn keine Daten vorhanden sind oder der Stream geschlossen ist.

Es sollte wahrscheinlich eine Option zum Blockieren für diesen Anwendungsfall bieten, aber wenn es mit einer echten Konsole verwendet wird, würde es für immer blockieren.

In der Zwischenzeit können Sie eine Kopie der Klasse erstellen könnte und ... ändern

@Override 
public Message<String> receive() { 
    try { 
     synchronized (this.monitor) { 
//   if (!this.reader.ready()) {   // remove this 
//    return null; 
//   } 
      String line = this.reader.readLine(); 
      if (line == null) {     // add this 
       ((ConfigurableApplicationContext) getApplicationContext()).close(); 
      } 
      return (line != null) ? new GenericMessage<String>(line) : null; 
     } 
    } 
    catch (IOException e) { 
     throw new MessagingException("IO failure occurred in adapter", e); 
    } 
} 

(Entfernen der fertig zu überprüfen, und den Kontext bei EOF heruntergefahren).

Ich öffnete eine JIRA Issue.

+0

Ich wollte nur hinzufügen, dass diese Lösung funktioniert, aber die Menschen sollten sich bewusst sein, dass in komplexeren Abläufen Nachrichten noch verarbeitet und durch den Fluss gehen können, die verloren gehen, wenn der Kontext geschlossen und alle Beans zerstört werden . Nicht sicher, wie man das anmutig tut, um diese Art von Situationen zu vermeiden. Aus diesem Grund habe ich die 'CharacterStreamReadingMessageSource' (mit einem Fix) nicht verwendet, sondern meine eigene 'StdinReader'-Klasse erstellt, die von einer Klasse aufgerufen wird, die' CommandLineRunner' implementiert und 'ThreadPoolExecutor' autowired, um Executor Shutdown zu erlauben . – xbranko