Killing a process using Java

JavaProcess

Java Problem Overview


I would like to know how to "kill" a process that has started up. I am aware of the Process API, but I am not sure, If I can use that to "kill" an already running process, such as firefox.exe etc. If the Process API can be used, can you please point me into the correct direction? If not, what are the other available options? Thanks.

Java Solutions


Solution 1 - Java

If you start the process from with in your Java application (ex. by calling Runtime.exec() or ProcessBuilder.start()) then you have a valid Process reference to it, and you can invoke the destroy() method in Process class to kill that particular process.

But be aware that if the process that you invoke creates new sub-processes, those may not be terminated (see http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4770092).

On the other hand, if you want to kill external processes (which you did not spawn from your Java app), then one thing you can do is to call O/S utilities which allow you to do that. For example, you can try a Runtime.exec() on kill command under Unix / Linux and check for return values to ensure that the application was killed or not (0 means success, -1 means error). But that of course will make your application platform dependent.

Solution 2 - Java

On Windows, you could use this command.

taskkill /F /IM <processname>.exe 

To kill it forcefully, you may use;

Runtime.getRuntime().exec("taskkill /F /IM <processname>.exe")

Solution 3 - Java

AFAIU java.lang.Process is the process created by java itself (like Runtime.exec('firefox'))

You can use system-dependant commands like

 Runtime rt = Runtime.getRuntime();
  if (System.getProperty("os.name").toLowerCase().indexOf("windows") > -1) 
     rt.exec("taskkill " +....);
   else
     rt.exec("kill -9 " +....);

Solution 4 - Java

With Java 9, we can use ProcessHandle which makes it easier to identify and control native processes:

ProcessHandle
  .allProcesses()
  .filter(p -> p.info().commandLine().map(c -> c.contains("firefox")).orElse(false))
  .findFirst()
  .ifPresent(ProcessHandle::destroy)

where "firefox" is the process to kill.

This:

  • First lists all processes running on the system as a Stream<ProcessHandle>

  • Lazily filters this stream to only keep processes whose launched command line contains "firefox". Both commandLine or command can be used depending on how we want to retrieve the process.

  • Finds the first filtered process meeting the filtering condition.

  • And if at least one process' command line contained "firefox", then kills it using destroy.

No import necessary as ProcessHandle is part of java.lang.

Solution 5 - Java

Accidentally i stumbled upon another way to do a force kill on Unix (for those who use Weblogic). This is cheaper and more elegant than running /bin/kill -9 via Runtime.exec().

import weblogic.nodemanager.util.Platform;
import weblogic.nodemanager.util.ProcessControl;
...
ProcessControl pctl = Platform.getProcessControl();
pctl.killProcess(pid);

And if you struggle to get the pid, you can use reflection on java.lang.UNIXProcess, e.g.:

Process proc = Runtime.getRuntime().exec(cmdarray, envp);
if (proc instanceof UNIXProcess) {
    Field f = proc.getClass().getDeclaredField("pid");
    f.setAccessible(true);
    int pid = f.get(proc);
}

Solution 6 - Java

It might be a java interpreter defect, but java on HPUX does not do a kill -9, but only a kill -TERM.

I did a small test testDestroy.java:

ProcessBuilder pb = new ProcessBuilder(args);
Process process = pb.start();
Thread.sleep(1000);
process.destroy();
process.waitFor();

And the invocation:

$ tusc -f -p -s signal,kill -e /opt/java1.5/bin/java testDestroy sh -c 'trap "echo TERM" TERM; sleep 10'

dies after 10s (not killed after 1s as expected) and shows:

...
[19999]   Received signal 15, SIGTERM, in waitpid(), [caught], no siginfo
[19998] kill(19999, SIGTERM) ............................................................................. = 0
...

Doing the same on windows seems to kill the process fine even if signal is handled (but that might be due to windows not using signals to destroy).

Actually i found https://stackoverflow.com/questions/10630303/java-process-destroy-source-code-for-linux related thread and openjava implementation seems to use -TERM as well, which seems very wrong.

Solution 7 - Java

Try it:

String command = "killall <your_proccess>";
Process p = Runtime.getRuntime().exec(command);
p.destroy();

if the process is still alive, add:

p.destroyForcibly();

Solution 8 - Java

You can kill a (SIGTERM) a windows process that was started from Java by calling the destroy method on the Process object. You can also kill any child Processes (since Java 9).

The following code starts a batch file, waits for ten seconds then kills all sub-processes and finally kills the batch process itself.

ProcessBuilder pb = new ProcessBuilder("cmd /c my_script.bat"));
Process p = pb.start();
p.waitFor(10, TimeUnit.SECONDS);

p.descendants().forEach(ph -> {
    ph.destroy();
});
			
p.destroy();
	

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionJeel ShahView Question on Stackoverflow
Solution 1 - JavaYohan LiyanageView Answer on Stackoverflow
Solution 2 - JavaLaksitha RanasinghaView Answer on Stackoverflow
Solution 3 - JavachroView Answer on Stackoverflow
Solution 4 - JavaXavier GuihotView Answer on Stackoverflow
Solution 5 - JavachukkoView Answer on Stackoverflow
Solution 6 - JavachukkoView Answer on Stackoverflow
Solution 7 - JavaHaysa RodriguesView Answer on Stackoverflow
Solution 8 - JavaJamie ListerView Answer on Stackoverflow