【问题标题】:Deciding between Apache Commons exec or ProcessBuilder在 Apache Commons exec 或 ProcessBuilder 之间做出决定
【发布时间】:2011-03-04 03:44:49
【问题描述】:
我正在尝试决定是使用 ProcessBuilder 还是 Commons exec,
我的要求是我只是想创建一个我不关心其 stdout/stdin/stderr 的守护进程。另外,我想在时机成熟时执行 kill 以销毁此进程。
我在 Linux 上使用 Java。
我知道两者都有自己的痛苦和陷阱(例如,确保使用单独的线程来吞下流会导致阻塞或死锁,并关闭流以免留下打开的文件)并且想知道是否有人有一种或另一种方式的建议以及任何好的资源可以遵循。
【问题讨论】:
标签:
java
process
apache-commons-exec
【解决方案1】:
commons-exec 不是我用过的最好的库,但它确实解决了 Java 进程调用中最大的缺陷,即正确处理/使用 stdout/sterr。我以前用过 ProcessBuilder,很好用,现在用 commons-exec 也很好,可以轻松处理大部分常见情况。
【解决方案2】:
如果你想使用守护进程,也许 Apache Commons Daemon 会更合适?
【解决方案3】:
Commons Daemon 将 Java 进程作为守护进程启动,但它并没有按照人们期望的方式进行。例如,当一个标准的 C 程序启动一个守护进程(以 apache 或 sshd 为例)时,它们会在分叉到后台之前执行一些配置完整性检查和其他事情(如锁定锁定文件)。 Apache Commons Daemon 是一个启动 java 应用程序的 c 程序,并且不允许您在 Java 代码 AFAIK 中进行健全性检查,因此破坏了我认为重要的守护程序设施。
因此,如果您希望实现一个行为类似于 sshd、apache 等的守护进程启动器,那么我建议您使用 commons exec。
【解决方案5】:
ZT Process Executor 库是 Apache Commons Exec 的替代品。它具有运行命令、捕获其输出、设置超时、验证程序退出状态等功能。
我已经使用了一点,我发现它设计得很好,文档也很合理。
文档中的示例
执行命令,将标准错误输出到记录器,将输出作为 UTF8 字符串返回。
String output = new ProcessExecutor().command("java", "-version")
.redirectError(Slf4jStream.of(getClass()).asInfo())
.readOutput(true).execute()
.outputUTF8();
其文档列出了与 Commons Exec 相比的以下优势:
- 改进了流的处理
- 读/写流
- 将标准错误重定向到标准输出
- 改进了超时处理
- 改进了退出代码检查
- 改进的 API
- 一个用于相当复杂用例的内衬
- 一个内衬将进程输出转换为字符串
- 可以访问 Process 对象
- 支持异步进程(未来)
- 使用SLF4J API 改进了日志记录
- 支持多个进程