Java 9 : How to use Java 9 Process Api
Introduction to Java 9 Process Api
The New Java 9 Processes API
will help provide
- Identifies the processess
- Control of Native processes
- Monitoring of processes
- List Children of processess
- Start a new Process
- Destroy a running process
- Access to the process input,output and error streams.
- On Exit Handle when a process is destroyed or completed.
Testing Process API operations
In this post java program we are testing the following operations
- List all processess running in the OS.
- Print the information of the current process.
- Create a new process and then terminate it.
- Do some action when the process is destroyed or completed.
- Try to terminate the current process.
- Destroy a process forcefully
- Get children of a process.
List all Processess
ProcessHandle.allProcesses()
is a static method in ProcessHandle interface that returns Stream<ProcessHandle>
object. We will iterate this stream to print the information of all the processess running.
package com.ekiras.java9.processapi;
import java.lang.ProcessHandle;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;
/**
* @author ekiras
*/
public class ListAllProcesses {
public static void main(String[] args){
allProcesses();
}
public static void allProcesses() {
System.out.println("Process list:");
Stream<ProcessHandle> processStream = ProcessHandle.allProcesses();
processStream.forEach(e -> printProcessInfo(e));
}
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());
}
}
The above code will produce the following output on console.
Process list: --------------------------------------------------------- Process Id :: 1 Process isAlive() :: true Process children :: 0 Process supportsNormalTermination() :: true Process Info :: [user: Optional[root], cmd: /bin/bash, startTime: Optional[2016-11-14T05:24:57.150Z], totalTime: Optional[PT0.02S]] --------------------------------------------------------- Process Id :: 15 Process isAlive() :: true Process children :: 1 Process supportsNormalTermination() :: true Process Info :: [user: Optional[root], cmd: /bin/bash, startTime: Optional[2016-11-14T05:25:06.670Z], totalTime: Optional[PT0.08S]] --------------------------------------------------------- Process Id :: 449 Process isAlive() :: true Process children :: 0 Process supportsNormalTermination() :: true Process Info :: [user: Optional[root], cmd: /opt/jdk-9/bin/java, args: [ListAllProcesses], startTime: Optional[2016-11-14T07:38:41.240Z], totalTime: Optional[PT0.35S]]
Current Process Information
In this example we will try to get information about the current process. For this we will use the method ProcessHandle.current()
method, this will return the object ProcessHandle
which can be used to get the information of the process.
import java.io.IOException;
import java.lang.ProcessHandle;
/**
* @author ekiras
*/
public class CurrentProcess {
public static void main(String[] args) throws IOException {
currentProcessInfo();
}
public static void currentProcessInfo(){
System.out.println("Current Process : ");
ProcessHandle process = ProcessHandle.current();
printProcessInfo(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());
}
}
The above code will produce the following output on console.
Current Process : --------------------------------------------------------- Process Id :: 551 Process isAlive() :: true Process children :: 0 Process supportsNormalTermination() :: true Process Info :: [user: Optional[root], cmd: /opt/jdk-9/bin/java, args: [CurrentProcess], startTime: Optional[2016-11-14T07:45:33.440Z], totalTime: Optional[PT0.24S]]
Terminating a Process
In this example we will terminate/destroy a running process using destroy()
method in the ProcessHandle
interface.
To test this we have started a process to run in background. e.g
tail -F /dev/null &;
Now we will destroy this process through our code.
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("---------------------------------------------------------");
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.destroy();
}
public static Process startProcess(String command) throws IOException {
System.out.println("Start Process :");
Runtime runtime = Runtime.getRuntime();
Process process = runtime.exec(command);
return process;
}
}
The above code will produce the following output on console.
Start Process : --------------------------------------------------------- Process Id :: 1259 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-14T15:52:01.670Z], totalTime: Optional[PT0S]] Going to destroy Process with id :: 1259 --------------------------------------------------------- Process Id :: 1259 Process isAlive() :: false Process children :: 0 Process supportsNormalTermination() :: true Process Info :: []
Terminating Current Process
We cannot destroy the current Process trying to destroy the current process will throw IllegalStateException
.
In this example we will try to destroy/terminate the current process to see what happens when we try to destroy the current process.
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.destroy();
}
}
The above code will produce the following output on console.
Current Process : --------------------------------------------------------- Process Id :: 653 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-14T08:32:28.640Z], totalTime: Optional[PT0.32S]] Going to destroy Process with id :: 653 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.destroy(ProcessHandleImpl.java:326) at DestroyCurrentProcess.destroyProcess(DestroyCurrentProcess.java:34) at DestroyCurrentProcess.currentProcessInfo(DestroyCurrentProcess.java:18) at DestroyCurrentProcess.main(DestroyCurrentProcess.java:11)
No comments: