2

Java から外部アプリケーションを実行する際に問題があります。入力ストリームと出力ストリームの問題を認識しており、次のように読み取ろうとしています。

    ProcessBuilder pb = new ProcessBuilder(args);
    args[args.length - 1] += "<NUL";

    pb.redirectErrorStream(true);
    Process p = pb.start();

    InputStreamReader isr = new InputStreamReader(p.getInputStream());
    BufferedReader input = new BufferedReader(isr);
    while (input.readLine() != null) {
    }       

    p.waitFor();
    input.close();
    isr.close();

私が実行しているコマンドは、URL に対して xdg-open であるため、入力を待つべきではありません。

これは、私のマシンでは 10 回中 9 回動作しますが、pb.start(); で単にハングすることもあります。コマンドは実行されません。

Java スレッドは、プロセスが戻るのを待っています。スタック トレースは次のとおりです。

Name: LinkHandlerExec
State: WAITING on java.lang.UNIXProcess$Gate@356122dc
Total blocked: 0  Total waited: 1

Stack trace: 
java.lang.Object.wait(Native Method)
java.lang.Object.wait(Object.java:502)
java.lang.UNIXProcess$Gate.waitForExit(UNIXProcess.java:80)
java.lang.UNIXProcess.<init>(UNIXProcess.java:161)
java.lang.ProcessImpl.start(ProcessImpl.java:81)
java.lang.ProcessBuilder.start(ProcessBuilder.java:468)

strace が教えてくれることは次のとおりです。

$ sudo strace -p 13255
Process 13255 attached - interrupt to quit
futex(0x7fbb673e49d0, FUTEX_WAIT, 13262, NULL
4

1 に答える 1

0

このような問題は、CentOS 6.3 JDK 1.6.0_33-b03 でも確認されています。調査の結果、これは、この Java プロセスで OutOfMemoryError が発生した後に発生することが示されました。

クラス java.lang.UNIXProcess のコードを見ると、109 行目と 130 行目の間のどこかで、UNIXProcess コンストラクター内の別のスレッド実行で非 IO 例外 (エラーなど) がスローされたときに、このような問題が発生する可能性があると思います。このコードのように整理したほうがよいでしょう。

try {
  .....
} finally {
  gate.exit();
}

、しかし代わりに次のように編成されています

try {
  ...
} catch (IOException e) {
  gate.setException(e); /*remember to rethrow later*/
  gate.exit();
  return;
}
...
gate.exit(); 

、したがって、非 IO 例外により、gate.exit() が呼び出されない可能性があります。これにより、メインの呼び出し元スレッドがメソッド gate.waitForExit() で永久にハングアップします (145 行目)。

于 2013-05-23T16:29:58.397 に答える