2016-09-21 15 views
1

私は春の統合の流れでCharacterStreamReadingMessageSourceを使用しています:CharacterStreamReadingMessageSource.stdin()とEOF

IntegrationFlows.from(CharacterStreamReadingMessageSource.stdin()) 

それは動作します。問題は、Iパイププロセスへのファイルの場合:

cat file | java -jar app.jar 

または

java -jar app.jar < file 

ファイルが読み込まれた後、EOFは、標準入力がまだアクティブで伝播されません

、およびプロセス終了しません。それをそうするために私ができることはありますか?手動でコマンドラインに ctrl-Zと入力すると、アプリケーションが終了します(Springブートアプリケーション、Webはありません)。

答えて

1

残念ながら、このシナリオでは機能しません。コンソール入力用に設計されています。

CharacterStreamReadingMessageSourceは、BufferedReaderSystem.inをラップし、readLine()を使用します。 readLine()ブロック以来、私たちは長い間スレッドを張りたいとは思わないので、データがないかストリームが閉じている場合はfalseを返すreader.ready()をチェックします。

おそらく、このユースケースをブロックするオプションを提供するはずですが、実際のコンソールで使用すると永遠にブロックされます。

一方で、あなたはクラスのコピーを作成し、を変更する可能性が...

@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); 
    } 
} 

(準備チェックを外すと、EOFでコンテキストをシャットダウンします)。

私はJIRA Issueをオープンしました。

+0

このソリューションが機能することを追加したければ、より複雑なフローではまだメッセージが処理され、フローが処理されてコンテキストが閉じられ、すべてのBeanが破棄される。このような状況を避けるために、これを正常に実行する方法がわかりません。そのため、私は 'CharacterStreamReadingMessageSource'(修正あり)を使わずに済みましたが、' CommandLineRunner'を実装するクラスから呼び出された自分自身の 'StdinReader'クラスを作成し、' ThreadPoolExecutor'をautowiredにしてエグゼキュータのシャットダウンを許可しました。 – xbranko