2012-02-21 13 views
0

コマンドラインコールでいくつかの他のプログラムを実行するために必要なプログラムを作成する必要があります。プログラム1は、プログラム2が読み込んだファイルを生成する。私はこれを安全に行う方法について様々な例を踏襲してきましたが、まだ厄介な問題が1つあります。以下のコードは大部分は動作しますが、waitfor()の後にsystem.outが存在する場合のみです。私がこれを取り除くと、私はエラーになります(下記参照)。なぜ何かが起こっているのか分からないと、私はコードに多少不快です。Javaランタイムプロセスwaitforが待機するようには見えない

助けてください。

コード:そのままのSystem.outラインと

public static int executeCommandWithOutputfile(String command, 
     String outputFile) { 
    int exitVal = 0; 

    try { 
     FileOutputStream fos = new FileOutputStream(outputFile); 
     Runtime rt = Runtime.getRuntime(); 
     Process proc = rt.exec(command); 

     // any error message? 
     StreamGobbler errorGobbler = new StreamGobbler(proc.getErrorStream(), 
      "ERROR"); 

     // any output? 
     StreamGobbler outputGobbler = new StreamGobbler(proc.getInputStream(), 
      "OUTPUT", fos); 

     // kick them off 
     errorGobbler.start(); 
     outputGobbler.start(); 

     // any error??? 
     exitVal = proc.waitFor(); 
     //don't remove this system out, when I did I got errors. 
     //System.out.println("ExitValue: " + exitVal); 
     fos.flush(); 
     fos.close(); 
    } catch (Throwable t) { 
     t.printStackTrace(); 
    } 
    return exitVal; 
} 

出力:削除のSystem.outと

ExitValue: 0 
    ExitValue: 0 
    ExitValue: 0 
    Release note complete. 

出力:

[Fatal Error] tmpRelNote2482381115742032425xml:1:1: Premature end of file. 
    Error : The XML config file is not valid! 
    Exception in thread "main" java.lang.NullPointerException 
     at rwe.release.CreateReleaseNote.insertReleaseInfo(CreateReleaseNote.java:96) 
     at rwe.release.CreateReleaseNote.writeReleaseNote(CreateReleaseNote.java:81) 
     at rwe.release.CreateReleaseNote.<init>(CreateReleaseNote.java:30) 
     at rwe.release.CreateReleaseNote.main(CreateReleaseNote.java:19) 
    Process exited with exit code 1. 
+0

例外が発生する箇所、この場合は 'insertReleaseInfo()'を表示する必要があります。 – Viruzzo

+0

waitFor()に達する前にエラーが発生しているようです。デバッガでコードをデバッグしようとすると、何が表示されますか? –

答えて

2

コードに競合状態があります。 fos.close()を呼び出したときに、OutputGobblerがプロセスの出力を停止する場合があります。 printlnは、ゴブラーがプロセスの出力を処理する時間を与えるのに十分なほどこのスレッドを遅くします。

である必要があります。ファイルを閉じる前にOutputGobblerがすべての出力をファイルに転送し終わっていることを確認してください。

+0

にerrorGobbler.join();およびoutputGobbler.join()が追加されました。すべてが今働く、デイヴィッドに感謝する – Chris

0

問題は確実にwaitFor()ですか?

私は、外部のコマンドのOutputStreamをフラッシュして、System.out.println()が問題を解決する理由を説明していると思います。 waitFor()が返った後で明示的なSystem.out.flush()を実行してみてください。

From Process javadoc:作成されたサブプロセスには、独自の端末またはコンソールがありません。標準のすべてのio(つまりstdin、stdout、stderr)操作は、3つのストリーム(getOutputStream()、getInputStream ()、getErrorStream())。 "

関連する問題