Java 9 Process API

java-9-process-api-feature-image

In this tutorial, we’re gonna look at new way of retrieving process information: all processes, current process, children processes and destroying process with Java 9 Process API.

I. New Process API
0. ProcessHandle Information

New Process API supports easy way to get many information of a process.
Here is some sample code to retrieve them from a ProcessHandle object:

	private static void printInfo(ProcessHandle processHandle) {
		System.out.println("---------");
		System.out.println("Id: " + processHandle.getPid());
		System.out.println("isAlive(): " + processHandle.isAlive());
		System.out.println("number of childrens: " + processHandle.children().count());
		System.out.println("isSupportsNormalTermination(): " + processHandle.supportsNormalTermination());

		ProcessHandle.Info processInfo = processHandle.info();
		System.out.println("Info: " + processInfo.toString());
		System.out.println("Info arguments().isPresent(): " + processInfo.arguments().isPresent());
		System.out.println("Info command().isPresent(): " + processInfo.command().isPresent());
		System.out.println("Info totalCpuDuration().isPresent(): " + processInfo.totalCpuDuration().isPresent());
		System.out.println("Info user().isPresent(): " + processInfo.user().isPresent());
	}

java.lang.ProcessHandle.Info is a public interface defined within interface java.lang.ProcessHandle.

All parts below will use this printInfo() function to display process information.

1. All processes

We retrieve all ProcessHandle data as a Stream using allProcesses() method.

		Stream processStream = ProcessHandle.allProcesses();
		processStream.forEach(process -> printInfo(process));

The result should be similar to:

---------
Id: 0
isAlive(): false
number of childrens: 104
isSupportsNormalTermination(): false
Info: []
Info arguments().isPresent(): false
Info command().isPresent(): false
Info totalCpuDuration().isPresent(): false
Info user().isPresent(): false
---------
Id: 4
isAlive(): false
number of childrens: 3
isSupportsNormalTermination(): false
Info: []
Info arguments().isPresent(): false
Info command().isPresent(): false
Info totalCpuDuration().isPresent(): false
Info user().isPresent(): false
---------
Id: 432
isAlive(): false
number of childrens: 0
isSupportsNormalTermination(): false
Info: []
Info arguments().isPresent(): false
Info command().isPresent(): false
Info totalCpuDuration().isPresent(): false
Info user().isPresent(): false
2. Current process
		ProcessHandle processHandle = ProcessHandle.current();
		printInfo(processHandle);

The result should be similar to:

---------
Id: 11460
isAlive(): true
number of childrens: 0
isSupportsNormalTermination(): false
Info: [user: Optional[Andrien\TienTN], cmd: C:\Program Files\Java\jdk-9\bin\javaw.exe, startTime: Optional[2017-03-07T12:37:02.363Z], totalTime: Optional[PT0.921875S]]
Info arguments().isPresent(): false
Info command().isPresent(): true
Info totalCpuDuration().isPresent(): true
Info user().isPresent(): true
3. Children processes

To get all children of a process, we use java.lang.ProcessHandle.children() method that return a Stream. Typically, a process which is not alive has no children.

The sample code gets the first process and retrieves its children processes information:

		Optional processHandle2 = ProcessHandle.allProcesses().findFirst();

		processHandle2.ifPresent(proc -> proc.children().forEach(child -> System.out
				.println("PID: [ " + child.getPid() + " ], Cmd: [ " + child.info().command() + " ]")));

The result should be similar to:

PID: [ 5992 ], Cmd: [ Optional.empty ]
PID: [ 1004 ], Cmd: [ Optional.empty ]
PID: [ 8632 ], Cmd: [ Optional.empty ]
PID: [ 5652 ], Cmd: [ Optional[C:\Windows\System32\sihost.exe] ]
PID: [ 8076 ], Cmd: [ Optional[C:\Windows\System32\svchost.exe] ]
PID: [ 8112 ], Cmd: [ Optional[C:\Program Files (x86)\NVIDIA Corporation\NvContainer\nvcontainer.exe] ]
PID: [ 9616 ], Cmd: [ Optional[C:\Windows\System32\taskhostw.exe] ]
PID: [ 12584 ], Cmd: [ Optional[C:\Windows\System32\igfxEM.exe] ]
PID: [ 2376 ], Cmd: [ Optional[C:\Windows\System32\RuntimeBroker.exe] ]
PID: [ 12260 ], Cmd: [ Optional[C:\Windows\explorer.exe] ]
PID: [ 8664 ], Cmd: [ Optional[C:\Windows\System32\igfxHK.exe] ]
PID: [ 13224 ], Cmd: [ Optional[C:\Windows\SystemApps\ShellExperienceHost_cw5n1h2txyewy\ShellExperienceHost.exe] ]
PID: [ 11648 ], Cmd: [ Optional[C:\Windows\System32\igfxTray.exe] ]
PID: [ 12692 ], Cmd: [ Optional.empty ]
PID: [ 13092 ], Cmd: [ Optional[C:\Windows\SystemApps\Microsoft.Windows.Cortana_cw5n1h2txyewy\SearchUI.exe] ]
4. Destroy process

To terminate/destroy a running process, we use destroy() method in the ProcessHandle interface.

		try {
			final Process process = new ProcessBuilder(javaCmd, "-cp", classpath, MainApp.class.getName()).start();

			ProcessHandle processHandle3 = process.toHandle();
			printInfo(processHandle3);
			destroyProcess(processHandle3); //call processHandle3.destroy();
			
			Thread.sleep(1000);
			printInfo(processHandle3);

		} catch (IOException e) {
			e.printStackTrace();
		}

The result should be similar to:

---------
Id: 9132
isAlive(): true
number of childrens: 0
isSupportsNormalTermination(): false
Info: [user: Optional[Andrien\TienTN], cmd: C:\Program Files\Java\jdk-9\bin\java.exe, startTime: Optional[2017-03-07T13:45:30.439Z], totalTime: Optional[PT0S]]
Info arguments().isPresent(): false
Info command().isPresent(): true
Info totalCpuDuration().isPresent(): true
Info user().isPresent(): true
Ready to destroy Process with id: 9132
---------------------------
After destroying the process:
---------
Id: 9132
isAlive(): false
number of childrens: 0
isSupportsNormalTermination(): false
Info: [user: Optional[Andrien\TienTN], startTime: Optional[2017-03-07T13:45:30.439Z], totalTime: Optional[PT0S]]
Info arguments().isPresent(): false
Info command().isPresent(): false
Info totalCpuDuration().isPresent(): true
Info user().isPresent(): true
II. Source code
package com.javasampleapproach.processapi;

import java.io.File;
import java.io.IOException;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Stream;

public class MainApp {

	public static void main(String[] args) throws InterruptedException {

		System.out.println("---------------------------");
		System.out.println("All Processes:");
		Stream processStream = ProcessHandle.allProcesses();
		processStream.forEach(process -> printInfo(process));

		System.out.println("---------------------------");
		System.out.println("Current Process:");
		ProcessHandle processHandle1 = ProcessHandle.current();
		printInfo(processHandle1);

		System.out.println("---------------------------");
		System.out.println("Children Processes:");
		Optional processHandle2 = ProcessHandle.allProcesses().findFirst();

		processHandle2.ifPresent(proc -> proc.children().forEach(child -> System.out
				.println("PID: [ " + child.getPid() + " ], Cmd: [ " + child.info().command() + " ]")));

		System.out.println("---------------------------");
		System.out.println("Destroy Process:");

		final String javaCmd = getJavaCmdFromParent();
		final String classpath = getClassPathFromParent();

		try {
			final Process process = new ProcessBuilder(javaCmd, "-cp", classpath, MainApp.class.getName()).start();

			ProcessHandle processHandle3 = process.toHandle();
			printInfo(processHandle3);
			destroyProcess(processHandle3);
			
			Thread.sleep(1000);
			System.out.println("---------------------------");
			System.out.println("After destroying the process:");
			printInfo(processHandle3);

		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	private static String getClassPathFromParent() {
		return System.getProperty("java.class.path", "./*");
	}

	private static String getJavaCmdFromParent() {

		return Objects.isNull(System.getProperty("java.home")) ? "java"
				: String.format("%s%sbin%sjava", System.getProperty("java.home"), File.separator, File.separator);
	}

	private static void destroyProcess(ProcessHandle processHandle) throws IllegalStateException {

		System.out.println("Ready to destroy Process with id: " + processHandle.getPid());
		processHandle.destroy();
	}

	private static void printInfo(ProcessHandle processHandle) {
		System.out.println("---------");
		System.out.println("Id: " + processHandle.getPid());
		System.out.println("isAlive(): " + processHandle.isAlive());
		System.out.println("number of childrens: " + processHandle.children().count());
		System.out.println("isSupportsNormalTermination(): " + processHandle.supportsNormalTermination());

		ProcessHandle.Info processInfo = processHandle.info();
		System.out.println("Info: " + processInfo.toString());
		System.out.println("Info arguments().isPresent(): " + processInfo.arguments().isPresent());
		System.out.println("Info command().isPresent(): " + processInfo.command().isPresent());
		System.out.println("Info totalCpuDuration().isPresent(): " + processInfo.totalCpuDuration().isPresent());
		System.out.println("Info user().isPresent(): " + processInfo.user().isPresent());
	}

}

Leave a Reply

Your email address will not be published. Required fields are marked *