优雅地杀死了Apache Commons Exec进程

时间:2011-03-02 22:39:25

标签: java unix apache-commons apache-commons-exec

我在我的Java程序中启动了一个外部进程(在Linux上),我需要能够发送一个SIGTERM信号而不是exec.getWatchdog().destroyProcess()发送的SIGKILL。有没有办法可以更优雅地停止使用commons-exec启动的unix进程?或者我可以获得PID,以便我可以自己运行相应的kill命令吗?

3 个答案:

答案 0 :(得分:7)

好吧,Commons Exec依赖于Java Process类,它不公开PID。它也是用来杀死进程的东西,所以你不能改变它的行为。一切都很好,封装起来。得爱OO,嗯?

如果您只是在后台启动进程,则可以将它们包装在一个简单的shell脚本中,该脚本为您捕获PID,然后将其保存到Java例程所知道的“已知位置”。仍然有点混乱,当然,它并没有很好地移植到其他平台。

您可以使用JNI编写自己的exec函数来为您捕获此信息,但这可能不太友好。

您可以在更面向系统(C,Python等)的东西中编写特定于平台的exec启动程序守护程序。您发送IT消息以启动和停止事务,并为您处理该过程。这样做的一个好处是,当您运行新进程时,您不必分叉JVM(根据您的JVM大小,这可能非常昂贵)。

您可以在开头启动守护程序并共享套接字或管道(两者都非常便携)。这实际上并不是一个非常简单的优雅解决方案,并且它划分了许多系统特定的行为(因此,你可以拥有一个完全不同的过程,例如,Windows vs Unix和你的Java保持不变,你只需要移植你的小守护进程),无需运行JNI。

答案 1 :(得分:7)

ExecuteWatchdog类有杀死进程的方法。

所以,你可以创建一个具有长超时的看门狗,并在必要时用它来杀死进程,即

executor.getWatchdog().destroyProcess();

答案 2 :(得分:0)

嗯,你可以grep它,因为前:

for i in $(ps -ef | grep -i "[Y]ourClassName" | awk '{print $2}'); do kill -9 $i; done

如果你运行的时间超过1次(虽然只有一个项目它可以工作),请注意grep中的[],这样grep就不会给你自己的进程pid和-i代表忽略大小写,awk仅用于打印第二列,即PID号。