-->

“Kill a process tree” on windows using Java

2019-02-17 19:10发布

问题:

I have a Java webstart process that is part of a windows batch script. I'm using the javaws command in a batch script in this case. This match script ( start.bat) is invoked programatically using the "apache commons exec". Under some conditions the java process invoked by javaws hangs and I'd have to kill the entire process thread starting from the batch script start.bat. Is there a programatic way of doing killing an entire process tree through apache commons exec?

I've tried using the "execWatchdog.destroyProcess();" on the "start.bat" script. However it only kills the start.bat process and not the entire process tree.

Is there a way of killing the entire process tree through apache-commons-exec or a similar code?

I've seen this question Performing equivalent of "Kill Process Tree" in c++ on windows that performs an equivalent task in c++. I'm wondering if anyone has implemented calling windows native system calls through JNI.

回答1:

Finally got something workable even though its a roundabout way.

Apache Commons Exec API contains the CommandLauncher class that returns a java.lang.Process object. Thanks to the link

Here the link to get the windows Process Id from a java.lang.Process. This uses the JNA libraries.

Finally with the Process Id, here the command string that kills the process tree //String killCmd = "taskkill /F /T /PID " + JNAHandler.getPid(process);



回答2:

Unfortunately, as you've discovered, there isn't a pure Java way of doing this. You'll have to resort to native commands or JNI libraries, all of which are platform-dependent and more complex than a pure Java solution would be.

It may be worth upvoting the relevant bug in the Java bug database: http://bugs.sun.com/view_bug.do?bug_id=4770092

With luck we can persuade the Java developers that the poor handling of subprocesses is worth fixing for Java 8.



回答3:

As far as I know, there's no such option in commons-exec. It's not even possible to obtain the PID of whatever process you just started. You could trap the kill signal within your bash script, and have the handler kill the subprocess(es) when the script process is killed.