我有一个Java webstart进程,它是Windows批处理脚本的一部分。在这种情况下,我在批处理脚本中使用javaws命令。 使用“apache commons exec”以编程方式调用此匹配脚本(start.bat)。在某些情况下,javaws调用的java进程会挂起,我必须从批处理脚本start.bat开始终止整个进程线程。 有没有通过apache commons exec杀死整个进程树的编程方法?
我尝试过使用“execWatchdog.destroyProcess();”在“start.bat”脚本上。但是它只会杀死start.bat进程而不是整个进程树。
有没有办法通过apache-commons-exec或类似代码杀死整个进程树?
我见过这个问题Performing equivalent of "Kill Process Tree" in c++ on windows在c ++中执行一个等价的任务。我想知道是否有人通过JNI实现了调用Windows本机系统调用。
答案 0 :(得分:8)
尽管它是一种迂回的方式,但最终得到了一些可行的东西。
Apache Commons Exec API包含返回java.lang.Process对象的CommandLauncher类。感谢link
这里是link从java.lang.Process获取windows Process Id。这使用JNA库。
最后使用Process Id,这里是杀死进程树的命令字符串 // String killCmd =“taskkill / F / T / PID”+ JNAHandler.getPid(process);
答案 1 :(得分:2)
不幸的是,正如您所发现的,没有纯Java方法可以做到这一点。您将不得不求助于本机命令或JNI库,所有这些都是依赖于平台的,并且比纯Java解决方案更复杂。
可能值得推荐Java bug数据库中的相关错误:http://bugs.sun.com/view_bug.do?bug_id=4770092
幸运的是,我们可以说服Java开发人员,对于Java 8来说,糟糕的子进程处理是值得的。
答案 2 :(得分:1)
据我所知,在commons-exec中没有这样的选择。甚至不可能获得刚开始的任何过程的PID。您可以在bash脚本中trap
终止信号,并让脚本进程终止时处理程序终止子进程。
答案 3 :(得分:1)
Java 版本 9 以后, Java 提出了可以查询和终止主进程及其后代的功能。 用于查询子进程的代码片段
import java.io.IOException;
public class ProcessTreeTest {
public static void main(String args[]) throws IOException {
Runtime.getRuntime().exec("cmd");
System.out.println("Showing children processes:");
ProcessHandle processHandle = ProcessHandle.current();
processHandle.children().forEach(childProcess ->
System.out.println("PID: " + childProcess.pid() + " Command: " + childProcess.info().command().get()));
System.out.println("Showing descendant processes:");
processHandle.descendants().forEach(descendantProcess ->
System.out.println("PID: " + descendantProcess.pid() + " Command: " + descendantProcess.info().command().get()));
}
}
为了杀死进程及其子进程,Java9 有 API
遍历进程的所有 children
并对每个进程调用 destroy
例如:在您的情况下,您是从 apache-commons 获取 Process 对象,然后尝试以下代码
Process child = ...;
kill (child.toHandle());
public void kill (ProcessHandle handle)
{
handle.descendants().forEach((child) -> kill(child));
handle.destroy();
}
参考资料:
https://docs.oracle.com/javase/9/docs/api/java/lang/ProcessHandle.html
https://www.tutorialspoint.com/how-to-traverse-a-process-tree-of-process-api-in-java-9
How do i terminate a process tree from Java?
<块引用>注意 - 我还没有尝试过这个功能,只是阅读了 Java9 和 发现在这里分享很有帮助。