2011-09-19 5 views
6

JavaのProcessBuilderを使用してサブプロセスを開始します。これは別のJavaプログラムで、別のJVMで実行する必要があります。Javaから開始されたサブプロセスはwaitForを使用して終了しますが、ストリームは終了しません。

ストリームバッファがいっぱいになるとハングしないように、プロセスからstdoutとstderrストリームを読み込むために2つのスレッドを開始します。 Process.waitForの呼び出しは戻りますが、ストリームは終了しません。

私はルックスにのようなもの(コマンドは、文字列のリストである)を使用していますコード:私は何かを実行する場合、このような「Javaの-version」または「DIR」か何か、コードとして、

ProcessBuilder pb = new ProcessBuilder(command); 

final Process p = pb.start(); 
final ByteArrayOutputStream outStream = new ByteArrayOutputStream(); 
final ByteArrayOutputStream errStream = new ByteArrayOutputStream(); 

Thread outputThread = new Thread() { 
    @Override 
    public void run() { 
     try { 
      IOUtils.copy(p.getInputStream(), outStream); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    }; 
}; 
outputThread.start(); 

Thread errorThread = new Thread() { 
    @Override 
    public void run() { 
     try { 
      IOUtils.copy(p.getErrorStream(), errStream); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    }; 
}; 
errorThread.start(); 

int returncode = p.waitFor(); 
outputThread.join(); 
errorThread.join(); 

を正常に動作します。 私は実行しようとしているJavaコードにアクセスできますが、System.outでclose()を呼び出す必要はありません。

+0

...行うことがより容易に多くの適切なストリーム:http://stackoverflow.com/questions/7065067/how-to-close-std -streams-java-lang-process-appropriate 別の便利なリンク:http://mark.koli.ch/2011/01/leaky-pipes-remember-to-close-your-streams-when-using- javas-runtimegetruntimeexec.html –

+0

'IOUtils.closeQuietly'を使うか、' join() 'が呼び出される前にストリームで' close() 'を呼び出すと、プログラムはその呼び出しでハングします。 –

+0

これは、 'IOUtils.copy(in、out)'が 'InputStream.read(byte [])'を使用し、受信データをブロックして待機しているためです。したがって、スレッドは永遠に実行されているため、 'join()'は永遠に待機します。指定されたタイムアウトを超えた後、ここで強制終了する必要があります。私があなたに与えたリンクから自分の答えに投稿したような実装を試してください。私はそれがここでこれを処理できると確信しています。 –

答えて

0

私が知っているように、this websiteから、自分でProcessオブジェクトのすべての標準ストリームを閉じる必要があります。前もって使用されているかどうかにかかわらず。これは、サブプロセスが終了しても明示的に閉じられていないときにパイプを開いたままにしておくG1ガベージコレクタ(Java 7 afaik以降のデフォルト)と非常に関係があります。

私は内部のここに慣れていませんが、my answerに投稿されたコードは、24時間体制のシステムでGhostScriptなどを大量に呼び出すと問題なく動作します。

SO明示的なプロセスSTD-ストリームをクローズしなければならないことを知らせる上の他の質問と回答:

3

のApache Commonsの幹部はあなたのためにすべてこれを行います。あなたがクローズ処理についての私の質問に興味がある可能性があり

http://commons.apache.org/exec/

関連する問題