2017-10-07 19 views
0

になっても、私はすでにWebを検索しました。質問process.waitFor() never returnsは、stdoutまたはstderrが読み込めないプロセスに問題があることがよくあります。Process.waitFor stdoutとstderrが読み込みを取得したにもかかわらず、応答が

私たちは、これを達成するために redirectOutputredirectErrorProcessBuilderを使用して、私たちは安全側にすべきだと思います、我々はプロセスを実行するために使用する以下の方法を参照

:問題はそれということで、

public static void execute(String directory, long timeout, File out, File err, String... command) throws InterruptedException, IOException { 
    LOGGER.log(Level.INFO, String.format("executing command %s (%s)", Arrays.toString(command), timeout > 0 ? String.format("timeout = %,d[ms]", timeout) : "no timeout")); 
    ProcessBuilder builder = new ProcessBuilder(); 
    builder.directory(new File(directory)); 
    builder.command(command); 
    builder.redirectOutput(out); 
    if(out == err) { 
     builder.redirectErrorStream(true);   
    } else { 
     builder.redirectError(err); 
    } 
    long time = System.currentTimeMillis(); 
    Process process = builder.start(); 
    try { 
     LOGGER.log(Level.FINE, "waiting for process"); 
     boolean exited = process.waitFor(timeout, TimeUnit.MILLISECONDS); 
     if(!exited) { 
      LOGGER.log(Level.WARNING, "timeout reached, trying to destroy ..."); 
      exited = destroy(silent, process); // Helper method to destroy processes 
     } 
     long duration = System.currentTimeMillis() - time; 
     int exitValue = process.exitValue(); 
     LOGGER.log(Level.INFO, "execution finished in " + duration + "[ms] => " + exitValue); 
    } catch (InterruptedException | Error | RuntimeException e) { 
     LOGGER.log(Level.SEVERE, "execution failed", e); 
     throw e; 
    } 
} 

はまだありませんプロセスがタイムアウト内で簡単に終了したとしても、process.waitFor(timeout, TimeUnit.MILLISECONDS)コールでハングします。

ログ出力がある

Oct 07, 2017 12:39:55 AM at.ProcessExecutor execute 
INFO: executing command [java, -Xmx8G, -XX:+UseG1GC, -XX:+CrashOnOutOfMemoryError, -jar, MetricCalc.jar] (timeout = 14,400,000[ms]) 
Oct 07, 2017 12:39:55 AM at.ProcessExecutor execute 
FINE: waiting for process 

errファイルが

... Things we write to std.err ... 
Finished Metrics 

を読み取り、MetricCalcの主な方法は

のように見えます(何 execution finishedラインはまだ書かれていないことを認識)
public static void main(String[] args) { 
    .... do some stuff ... 
    System.err.println("Finished Metrics"); 
} 

読み取りが正常に動作していることを示します。Javaプログラムの最後の行が実行され、プロセスが終了しているはずです。

プロセスが終了しない理由を知っている人は誰でも、まだProcess.waitFor()にハングアップしていますか?

+1

* "....そしてプロセスは終了しているはずです" * - 子プロセスが期待通りに動作していると仮定します。子プロセスが実際に終了したかどうかを確認してください。例えば"ps -efl"などを使用します。 –

+0

@StephenC:それでも 'ps -efl |それが終了していないことを示すgrep "java -Xmx8G" ' しかし、MetricCalcのコードの最後の行(プロセスとして実行されるJavaプログラム)が実行されて以来、なぜこれが当てはまるのかわかりません... –

+1

ああ、ちょうど私の心に来ました:おそらくMetricCalcいくつかのnon-deamonスレッドが走っているので、アプリケーションが終了するのを防ぐことができます。これをテストする必要があります... –

答えて

0

Process.waitFor()では問題ありませんでしたが、プロセスの終了に問題がありました。

開始されたjavaアプリケーションでは、ショットダウンが正しく行われなかったExecutorServiceが使用され、プロセス終了を妨げるゾンビスレッドが残っていました。

executorService.shutdown()を追加すると問題が解決され、アプリケーションは期待通りに終了します。

関連する問題