我正在使用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()。
答案 0 :(得分:3)
Apache commons exec为您完成所有这些。更容易做...
答案 1 :(得分:0)
据我所知this website,你必须自己关闭Process对象的所有std-stream。无论之前是否使用过。这似乎与G1垃圾收集器(默认情况下自Java 7 afaik)高度相关,它在未显式关闭时保持管道打开 - 即使子进程终止。
我对这里的内部不熟悉,但是我在my answer中发布的代码我的问题在一个24/7系统上工作正常,可以调用GhostScript和其他很多。
有关SO的其他问题和答案,说明您必须关闭进程'std-streams explicit: