从Java开始的子进程使用waitFor完成,但流不会终止

时间:2011-09-19 14:51:30

标签: java processbuilder

我正在使用Java的ProcessBuilder来启动一个子进程,这是另一个必须在单独的JVM中运行的Java程序。

我启动两个Threads来从Process读取stdout和stderr流,这样如果流缓冲区已满就没有挂起。 对Process.waitFor的调用返回但流不会终止。

我使用的代码看起来像(命令是字符串列表):

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 -version”或“dir”或其他东西,代码运行正常。 我可以访问我尝试运行的Java代码,但我从未听说过你应该在System.out上调用close()。

2 个答案:

答案 0 :(得分:3)

Apache commons exec为您完成所有这些。更容易做...

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

答案 1 :(得分:0)

据我所知this website,你必须自己关闭Process对象的所有std-stream。无论之前是否使用过。这似乎与G1垃圾收集器(默认情况下自Java 7 afaik)高度相关,它在未显式关闭时保持管道打开 - 即使子进程终止。

我对这里的内部不熟悉,但是我在my answer中发布的代码我的问题在一个24/7系统上工作正常,可以调用GhostScript和其他很多。

有关SO的其他问题和答案,说明您必须关闭进程'std-streams explicit: