Java 9 : How to Terminating or Destroy a Running Process

Points To Remember

  1. You cannot destroy or terminate the current process not even forcefully.
  2. You can destroy a process by using the methods destroy() or forcefully using destroyForcibly().

Read More

Destroy a Process

There are two methods in interface ProcessHandle that can be used to destroy a process.

  1. destroy() - to destroy a process noramally
  2. destroyForcibly() - to destroy a process forcefully. However the process may not be terminatted instantly since operating system access controls may prevent the process from being killed thus resulting in case where isAlive() method may return true for 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 :

Post a Comment