Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to kill subprocesses of a Java process?

I am creating a process P1 by using Process P1= Runtime.exec(...). My process P1 is creating another process say P2, P3....

Then I want to kill process P1 and all the processes created by P1 i.e. P2, P3...

P1.destroy() is killing P1 only, not its sub processes.

I also Googled it and found it's a Java bug: http://bugs.sun.com/view_bug.do?bug_id=4770092

Does anyone have any ideas on how to do it?

like image 490
vermap Avatar asked May 04 '11 07:05

vermap


3 Answers

Yes, it is a Bug, but if you read the evaluation the underlying problem is that it is next to impossible to implement "kill all the little children" on Windows.

The answer is that P1 needs to be responsible for doing its own tidy-up.

like image 57
Stephen C Avatar answered Sep 19 '22 12:09

Stephen C


Java does not expose any information on process grandchildren with good reason. If your child process starts another process then it is up to the child process to manage them.

I would suggest either

  • Refactoring your design so that your parent creates/controls all child processes, or
  • Using operating system commands to destroy processes, or
  • Using another mechanism of control like some form of Inter-Process Communication (there are plenty of Java libraries out there designed for this).

Props to @Giacomo for suggesting the IPC before me.

like image 37
Bringer128 Avatar answered Sep 18 '22 12:09

Bringer128


I had a similar issue where I started a PowerShell Process which started a Ping Process, and when I stopped my Java Application the PowerShell Process would die (I would use Process.destroy() to kill it) but the Ping Process it created wouldn't.

After messing around with it this method was able to do the trick:

private void stopProcess(Process process) {
    process.descendants().forEach(new Consumer<ProcessHandle>() {
        @Override
        public void accept(ProcessHandle t) {
            t.destroy();
        }
    });
    process.destroy();
}

It kills the given Process and all of its sub-processes.

PS: You need Java 9 to use the Process.descendants() method.

like image 40
PabloJ Avatar answered Sep 19 '22 12:09

PabloJ