Process API Improvement
Java has improved its process API in Java 9 version by adding new methods in Process class and new interfaces ProcessHandle and ProcessHandle.Info.
It is helpful in controlling and managing processes whether OS-based or application processes. We can create processes, get information about processes like process id, owner name, waiting time, process status, etc.
Two new interfaces in Process API:
- java.lang.ProcessHandle
- java.lang.ProcessHandle.Info
The Process class in Java provides several methods to handle the process and perform operations like check waiting for the process to complete, checking the exit status of the process, and destroying (killing) the process, etc.
The following are some methods that added in Java 9 version to the Process class.
Java Process class Methods (Only Java 9 methods)
Method |
Description |
boolean supportsNormalTermination()
|
It returns true if the implementation of destroy() is to normally terminate the process, else returns false.
|
ProcessHandle toHandle()
|
It returns a ProcessHandle for the Process.
|
long pid()
|
It returns the native process ID of the process.
|
Stream<ProcessHandle> children()
|
It returns a snapshot of the direct children of the process.
|
Stream<ProcessHandle> descendants()
|
It returns a snapshot of the descendants of the process.
|
ProcessHandle.Info info()
|
It returns a snapshot of information about the process.
|
CompletableFuture<Process> onExit()
|
It returns a CompletableFuture<Process> for the termination of the Process.
|
Example: Find Process Id
Let's understand the process handling by a simple example. Here, we are getting process id using the pid() method of Process class.
public class Main {
public static void main(String[] args){
ProcessHandle currentProcess = ProcessHandle.current();
System.out.println("Process Id: "+currentProcess.pid());
}
}
Process Id: 16458
Java ProcessHandle Interface
Java added this interface that identifies and provides control of native processes. It can be helpful to get list of its children, information of a process or destroy a process etc. The syntax of the method is given below.
public interface ProcessHandle extends Comparable<ProcessHandle>
Interface Methods
Following are the methods of ProcessHandle Interface. It contains one nested interface called Info.
Method |
Description |
static Stream<ProcessHandle> allProcesses()
|
It returns a snapshot of all processes visible to the current process.
|
Stream<ProcessHandle> children()
|
It returns a snapshot of the current direct children of the process.
|
int
compareTo(ProcessHandle other)
|
|
|
It compares this ProcessHandle with the specified ProcessHandle for order.
|
static ProcessHandle current()
|
It returns a ProcessHandle for the current process.
|
Stream<ProcessHandle> descendants()
|
It returns a snapshot of the descendants of the process.
|
boolean destroy()
|
It requests the process to be killed.
|
boolean destroyForcibly()
|
It requests the process to be killed forcibly.
|
boolean equals(Object other)
|
It returns true if other object is non-null, is of the same implementation, and represents the same system process; otherwise it It returns false.
|
int hashCode()
|
It returns a hash code value for this ProcessHandle.
|
ProcessHandle.Info info()
|
It returns a snapshot of information about the process.
|
boolean isAlive()
|
It tests whether the process represented by this ProcessHandle is alive.
|
static Optional<ProcessHandle> of(long pid)
|
It returns an Optional<ProcessHandle> for an existing native process.
|
CompletableFuture<ProcessHandle> onExit()
|
It returns a CompletableFuture<ProcessHandle> for the termination of the process.
|
Optional<ProcessHandle> parent()
|
It returns an Optional<ProcessHandle> for the parent process.
|
long pid()
|
It returns the native process ID of the process.
|
boolean supportsNormalTermination()
|
It returns true if the implementation of destroy() normally terminates the process.
|
In our previous example, we fetched the process id of the currently running process. However, we can start a new process by own and handle it.
Example: Start Vi Editor in Linux
Now, let's create a new process by using the start() method of ProcessBuilder class. Here, we are starting a process of vim editor in Linux and getting process id using the pid() method.
public class Main {
public static void main(String[] args) throws IOException{
Process p = new ProcessBuilder("vim").start();
System.out.println(p.pid());
}
}
13834
Example: Process Information
This example explains how can we get information of a process. We used pid(), isAlive(), info(), hashCode(), etc methods of Process class.
import java.io.IOException;
public class Main {
public static void main(String[] args) throws IOException{
Process p = new ProcessBuilder("vim").start();
// Get process ID
System.out.println(p.pid());
// Check is Alive?
System.out.println(p.isAlive());
// Get process Info
System.out.println(p.info());
// Get Hahscode
System.out.println(p.hashCode());
// Get child process
System.out.println(p.children());
// Get className
System.out.println(p.getClass());
}
}
14413
true
[user: Optional[root], cmd: /usr/bin/vim.basic, startTime: Optional[2020-07-23T19:02:42.310Z], totalTime: Optional[PT0S]]
1418481495
java.util.stream.ReferencePipeline$2@65ab7765
class java.lang.ProcessImpl
Java ProcessHandle.Info Interface
This interface provides information snapshots about the process. It is a nested interface of ProcessHandle interface. Each operating system's process attributes are not similar and are not available in all implementations. Information about processes is limited by the operating system privileges of the process making the request. The signature of this interface is given below.
public static interface ProcessHandle.Info
ProcessHandle.Info Methods
The following are the methods of ProcessHandle.info interface which is a static and nested interface
Method |
Description |
Optional<String[]> arguments()
|
It returns an array of Strings of the arguments of the process.
|
Optional<String> command()
|
It returns the executable pathname of the process.
|
Optional<String> commandLine()
|
It returns the command line of the process.
|
Optional<Instant> startInstant()
|
It returns the start time of the process.
|
Optional<Duration> totalCpuDuration()
|
It returns the total cputime accumulated of the process.
|
Optional<String> user()
|
It returns the user of the process.
|
Example:
Here, we are using ProcessHandle.Info interface methods to get information about the process.
import java.io.IOException;
import java.time.Duration;
public class Main {
public static void main(String[] args) throws IOException{
ProcessHandle.Info info = ProcessHandle.current().info();
System.out.println(info.arguments());
System.out.println(info.command().orElse("Not Found"));
String[] argz = info.arguments().orElse(new String[] {});
for (String arg: argz)
System.out.printf(" %s%n", arg);
System.out.println("Owner: "+info.user());
System.out.println("RunTime: "+info.totalCpuDuration().orElse(Duration.ofMillis(0)).toMillis());
}
}
Optional[[Ljava.lang.String;@1f32e575]
/usr/lib/jvm/java-11-openjdk-amd64/bin/java
-Dfile.encoding=UTF-8
-classpath
/home/root/eclipse/myjavaproject/bin:/home/root/Downloads/mongo-java-driver-3.12.4.jar:/home/root/Downloads/opencsv-3.8.jar:/home/root/Downloads/commons-logging-1.2/commons-logging-1.2.jar:/home/root/Downloads/pdfbox-2.0.12.jar:/home/root/Downloads/fontbox-2.0.12.jar
myjavaproject.Main
Owner: Optional[root]
RunTime: 100