Java 9 : How to Terminating or Destroy a Running Process
Points To Remember
- You 
cannot destroy or terminate the current processnot even forcefully. - You can destroy a process by using the methods 
destroy()or forcefully usingdestroyForcibly(). 
Read More
Destroy a Process
There are two methods in interface ProcessHandle that can be used to destroy a process.
destroy()- to destroy a process noramallydestroyForcibly()- to destroy a process forcefully. However the process may not be terminatted instantly sinceoperating system access controls may prevent the process from being killedthus resulting in case whereisAlive() method may return truefor a brief period after destroyForcibly() is called.
In the example below we will first create a process and then kill it forcefully.
import java.io.IOException;
import java.lang.ProcessHandle;
import java.lang.Process;
/**
 * @author ekiras
 */
public class DestroyProcess {
    public static void main(String[] args) throws InterruptedException {
        try {
            ProcessHandle processHandle = startProcess("tail -F /dev/null").toHandle();
            printProcessInfo(processHandle);
            destroyProcess(processHandle);
            Thread.sleep(1000);
            printProcessInfo(processHandle);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    public static void printProcessInfo(ProcessHandle processHandle){
        System.out.println("---Process Info---");
        System.out.println(" Process Id :: " + processHandle.getPid());
        System.out.println(" Process isAlive() :: " + processHandle.isAlive());
        System.out.println(" Process children :: " + processHandle.children().count());
        System.out.println(" Process supportsNormalTermination() :: " + processHandle.supportsNormalTermination());
        System.out.println(" Process Info :: " + processHandle.info().toString());
    }
    public static void destroyProcess(ProcessHandle process) throws IllegalStateException{
        System.out.println("Going to destroy Process with id :: " + process.getPid());
        process.destroyForcibly();
    }
    public static Process startProcess(String command) throws IOException {
        System.out.println("Start Process :");
        Runtime runtime = Runtime.getRuntime();
        Process process = runtime.exec(command);
        return process;
    }
}
In the above code we have used Thread.sleep(1000); to wait for the process to be terminated since operating system access controls may prevent the process from being killed and isAlive() method may return true for a brief period of time. This code will return the following output.
Start Process : ---Process Info--- Process Id :: 161 Process isAlive() :: true Process children :: 0 Process supportsNormalTermination() :: true Process Info :: [user: Optional[root], cmd: /usr/bin/tail, args: [-F, /dev/null], startTime: Optional[2016-11-28T18:52:48.540Z], totalTime: Optional[PT0S]] Going to destroy Process with id :: 161 ---Process Info--- Process Id :: 161 Process isAlive() :: false Process children :: 0 Process supportsNormalTermination() :: true Process Info :: []
Trying to Destroy Current Process
As already stated, you cannot destroy the current process even forcefully. Doing so will throw IllegalStateException. Lets take a look at the exxample.
import java.io.IOException;
import java.lang.ProcessHandle;
/**
 * @author ekiras
 */
public class DestroyCurrentProcess {
    public static void main(String[] args) throws IOException {
        currentProcessInfo();
    }
    public static void currentProcessInfo(){
        System.out.println("Current Process : ");
        ProcessHandle process = ProcessHandle.current();
        printProcessInfo(process);
        destroyProcess(process);
    }
    public static void printProcessInfo(ProcessHandle processHandle){
        System.out.println("---------------------------------------------------------");
        System.out.println(" Process Id :: " + processHandle.getPid());
        System.out.println(" Process isAlive() :: " + processHandle.isAlive());
        System.out.println(" Process children :: " + processHandle.children().count());
        System.out.println(" Process supportsNormalTermination() :: " + processHandle.supportsNormalTermination());
        System.out.println(" Process Info :: " + processHandle.info().toString());
    }
    public static void destroyProcess(ProcessHandle process) throws IllegalStateException{
        System.out.println("Going to destroy Process with id :: " + process.getPid());
        process.destroyForcibly();
    }
}
This will throw the error is shown below.
Current Process : 
---------------------------------------------------------
 Process Id :: 84
 Process isAlive() :: true
 Process children :: 0
 Process supportsNormalTermination() :: true
 Process Info :: [user: Optional[root], cmd: /opt/jdk-9/bin/java, args: [DestroyCurrentProcess], startTime: Optional[2016-11-28T18:45:24.700Z], totalTime: Optional[PT0.34S]]
Going to destroy Process with id :: 84
Exception in thread "main" java.lang.IllegalStateException: destroy of current process not allowed
    at java.base/java.lang.ProcessHandleImpl.destroyProcess(ProcessHandleImpl.java:308)
    at java.base/java.lang.ProcessHandleImpl.destroyForcibly(ProcessHandleImpl.java:331)
    at DestroyCurrentProcess.destroyProcess(DestroyCurrentProcess.java:34)
    at DestroyCurrentProcess.currentProcessInfo(DestroyCurrentProcess.java:18)
    at DestroyCurrentProcess.main(DestroyCurrentProcess.java:11)
No comments: