What’s new with Process API in JAVA 9?

Reading Time: 4 minutes

With the introduction of Java 9, various improvements have been made in the Process API. Process API in Java 9 version helps to manage and control operating system processes. In Java 8 and earlier versions, the API lacks some key functionality, which makes handling processes in Java a mess. The limitations of the API often force developers to resort to native code in earlier Java versions. Now, new classes and interfaces are added to perform this task.

As we know, the Process API provides control of native processes. The class provides methods for performing input from the process, performing output to the process, waiting for the process to complete, checking the exit status of the process, and destroying (killing) the process.

What are the new features of the ProcessAPI in Java 9?

The Process API lacks some key functionality, so developers have to write a messy code to perform those tasks. For example, in order to do something as simple as getting your process PID in earlier versions of Java, you would need to either access native code or use some sort of a workaround. The process of doing so is very cumbersome.

Java 9 comes to fix those issues and provide a clean API for interaction with processes. It enhances the Process class and introduces ProcessHandle with its nested interface Info to overcome the limitations we had in the past. More specifically two new interfaces have been added to the JDK:

1. java.lang.ProcessHandle
2. java.lang.ProcessHandle.Info

ProcessHandle:

ProcessHandle identifies and provides control of native processes. Each individual process can be monitored for liveness, list its children, get information about the process or destroy it. By comparison, Process instances were started by the current process and additionally provide access to the process input, output, and error streams.

Modifier and Type 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 the 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 another object is non-null, is of the same implementation, and represents the same system process; otherwise, 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.

ProcessHandle.Info:

ProcessHandle.Info gives information snapshot about the process. The attributes of a process vary by the operating system and are not available in all implementations. Information about processes is limited by the operating system privileges of the process making the request. The return types are Optional<T> allowing explicit tests and actions if the value is available.

Modifier and Type 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 CPU time accumulated of the process.
Optional<String> user() It returns the user of the process.

Let’s look at a few examples to understand the above two interfaces in a better way.

public class ProcessApiDemo {

    public static void main(String[] args) {
        ProcessHandle currentProcessHandleImpl = ProcessHandle.current();

        System.out.println("Native process ID of the process: " + currentProcessHandleImpl.pid()); //Get process Id of current native process
        System.out.println("\nDirect children: " + currentProcessHandleImpl.children()); // Direct children of the process
        System.out.println("\nClass name: " + currentProcessHandleImpl.getClass());       // Class name
        System.out.println("\nAll processes: " + ProcessHandle.allProcesses()); // All current processes
        System.out.println("\nProcess info: " + currentProcessHandleImpl.info());         // Process info
        System.out.println("\nIs process alive: " + currentProcessHandleImpl.isAlive());
        System.out.println("\nProcess's parent " + currentProcessHandleImpl.parent());  // Parent of the process

        //Process snapshot of the current running process with ProcessHandle.Info:
        ProcessHandle.Info processInfo = currentProcessHandleImpl.info();

        System.out.println("\nProcess snapshot of the current running process:");
        System.out.println("User : " + processInfo.user().get());
        System.out.println("Start Time : " + processInfo.startInstant().get());
    }
}

In the above example, we have seen various methods associated wit ProcessHandle and ProcessHandle.Info that can be leveraged in our code to work with the system’s processes in a better way.

Conclusion:

ProcessHandle identifies and provides control of native processes. Each individual process can be monitored for liveness, list its children, get information about the process or destroy it.

Using the java.lang.ProcessHandle.Info API, we can now obtain a lot of information about the process like:

  • the command used to start the process
  • the arguments of the command
  • time instant when the process was started
  • total time spent by it and the user who created it

I hope, you have liked my blog. If you have any doubts or suggestions to make please drop a comment. Thanks!

References:
Process API official doc
blog-footer

 

Written by 

Vinisha Sharma is a software consultant having more than 6 months of experience. She thrives in a fast pace environment and loves exploring new technologies. She has experience with the languages such as C, C++, Java, Scala and is currently working on Java 8. Her hobbies include sketching and dancing. She believes Optimism and a learning attitude is the key to achieve success in your life