I am using Runtime.getRuntime().exec() command to start a batch file which in turn starts another process for windows platform.
javaw.exe(Process1)
|___xyz.bat(Process2)
|___javaw.exe(Process3)
Runtime.getRuntime().exec() returns a Process object which has a destroy method, but when I use destroy(), it kills only the xyz.bat and leaves the batch file’s sub-process dangling.
Is there a clean way in to destroy the process tree starting with the batch process as root?
For the record I cannot use any custom libraries to get rid of the batch file to by-pass the issue.
This is not possible using the standard Java API (see edit at end of the post for an update that changes this). You will need some native code of some variety. Using JNA, I’ve used code that looks like this:
}
This code uses the following JNA declarations that are not included in the standard JNA library:
You can then use the ‘getChildren()’ method to get a list of children, terminate the parent, and then recursively terminate the children.
I believe you can extra the PID of a java.lang.Process using reflection (I haven’t done this, however; I switched to creating the processes myself using the Win32 API so that I would have more control over it).
So putting it together, you’d need something like:
Edit
It turns out that this particular shortcoming of the Java API is being fixed in Java 9. See the preview of the Java 9 documentation here (if the correct page doesn’t load, you need to look at the
java.lang.ProcessHandleinterface). For the requirement of the question above, the code would now look something like this:(Note that this isn’t tested – I haven’t switched to Java 9 yet, but am actively reading about it)