Java ProcessBuilder:外部进程挂起

时间:2009-10-29 12:55:31

标签: java process stream blocking processbuilder

我正在使用Java的ProcessBuilder类来运行外部进程。该过程不应该在Java程序之前终止;它必须在命令/响应模式下保持活跃状态​​。

我知道如果忽略过程流可能很容易“堵塞”,所以我做了以下事情: 程序在“reader”线程中读取进程的组合输出和错误流,并使用“writer”线程来管理命令。读取器线程阻止从进程输出中读取字符,将它们缓冲到字符串中并调度结果。 writer线程通过PrintWriter写入完整的“命令”行;它使用一个队列来确保没有两个命令写入“太靠近”(当前为100ms),并且在前一个命令的输出完成之前没有写入新命令。我也在每个println()之后调用flush()和checkError()。

此方案可以正常工作几秒钟或几分钟,然后读取器线程挂起阻塞读取()。没有错误,没有抛出异常,没有更多的进程输出。此后,没有什么能够恢复外部过程(重新启动它)。 (顺便说一下,这种情况发生在Linux和Windows上。)

我查看了Jakarta Commons Exec和Plexus Utils http://plexus.codehaus.org/plexus-utils/中的代码和测试用例,但(a)没有给出使用长期过程的示例,(b)似乎都没有做任何与我所描述的完全不同的事情。

有没有人知道这里发生了什么? 谢谢!

3 个答案:

答案 0 :(得分:1)

你还有一个管理stderr的线程吗?你只提到了两个流。

答案 1 :(得分:1)

我在三个单独的线程中实现了错误,输入和输出流,我可以读取和写入外部进程而没有任何问题。

我在windows / linux上测试了大量的内置应用程序cmd / bash以及其他cmd行二进制文件,它工作正常除了在某些情况下它只是抛出io流异常,我做的是捕获异常并重新启动再次线程,以便程序继续工作。

如果你试图在Linux中使用ssh,那么你可能遇到问题,就像你无法写入同一个stdin一样,这是出于安全原因。

尝试从System.in获取输入并查看它是否有效,它在我的情况下起作用

答案 2 :(得分:0)

只是一个猜测,但您是否尝试过合并错误和输出流?