Path: blob/master/test/jdk/java/lang/ProcessHandle/ProcessUtil.java
41149 views
/*1* Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223import java.io.IOException;24import java.lang.management.ManagementFactory;25import java.time.Duration;26import java.util.List;27import java.util.stream.Collectors;28import java.util.stream.Stream;2930import com.sun.management.OperatingSystemMXBean;31import jdk.test.lib.Platform;3233/**34* Useful utilities for testing Process and ProcessHandle.35*/36public abstract class ProcessUtil {37/**38* Constructor39*/40public ProcessUtil() {}4142/**43* Returns the list of direct children.44* WIndows conhost.exe children are filtered out.45* @param ph the Process to get children of46* @return a list of child ProcessHandles47*/48public static List<ProcessHandle> getChildren(ProcessHandle ph) {49return ph.children()50.filter(ProcessUtil::isNotWindowsConsole)51.collect(Collectors.toList());52}5354/**55* Returns the list of all direct and indirect children.56* WIndows conhost.exe children are filtered out.57* @param ph the Process to get children of58* @return a list of child ProcessHandles59*/60public static List<ProcessHandle> getDescendants(ProcessHandle ph) {61return ph.descendants()62.filter(ProcessUtil::isNotWindowsConsole)63.collect(Collectors.toList());64}6566/**67* Waits for and returns the direct expected Children of a ProcessHandle.68* For Windows, the conhost.exe children are filtered out.69*70* @param ph the process to get the children of71* @param nchildren the minimum number of children to expect72* @return a list of ProcessHandles of the children.73*/74public static List<ProcessHandle> waitForChildren(ProcessHandle ph, long nchildren) {75List<ProcessHandle> subprocesses = null;76long count = 0;77do {78if (subprocesses != null) {79// Only wait if this is not the first time looking80try {81Thread.sleep(500L); // It will happen but don't burn the cpu82} catch (InterruptedException ie) {83// ignore84}85}86subprocesses = getChildren(ph);87count = subprocesses.size();88System.out.printf(" waiting for subprocesses of %s to start," +89" expected: %d, current: %d%n", ph, nchildren, count);90} while (count < nchildren);91return subprocesses;92}9394/**95* Waits for and returns all expected Children of a ProcessHandle.96* For Windows, the conhost.exe children are filtered out.97*98* @param ph the process to get the children of99* @param nchildren the minimum number of children to expect100* @return a list of ProcessHandles of the children.101*/102public static List<ProcessHandle> waitForAllChildren(ProcessHandle ph, long nchildren) {103List<ProcessHandle> subprocesses = null;104long count = 0;105do {106if (subprocesses != null) {107// Only wait if this is not the first time looking108try {109Thread.sleep(500L); // It will happen but don't burn the cpu110} catch (InterruptedException ie) {111// ignore112}113}114subprocesses = getDescendants(ph);115count = subprocesses.size();116System.out.printf(" waiting for subprocesses of %s to start," +117" expected: %d, current: %d%n", ph, nchildren, count);118} while (count < nchildren);119return subprocesses;120}121122/**123* Destroy all children of the ProcessHandle.124* (Except the conhost.exe on Windows)125*126* @param p a ProcessHandle127* @return the ProcessHandle128*/129public static ProcessHandle destroyProcessTree(ProcessHandle p) {130Stream<ProcessHandle> children = p.descendants().filter(ProcessUtil::isNotWindowsConsole);131children.forEach(ph -> {132System.out.printf("destroyProcessTree destroyForcibly%n");133printProcess(ph);134ph.destroyForcibly();135});136return p;137}138139/**140* The OSMXBean for this process.141*/142public static final OperatingSystemMXBean osMbean =143(OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean();144145/**146* Return the CPU time of the current process according to the OperatingSystemMXBean.147*148* @return the CPU time of the current process149*/150public static Duration MXBeanCpuTime() {151return Duration.ofNanos(osMbean.getProcessCpuTime());152}153154/**155* Return true if the ProcessHandle is a Windows i586 conhost.exe process.156*157* @param p the processHandle of the Process158* @return Return true if the ProcessHandle is for a Windows i586 conhost.exe process159*/160static boolean isWindowsConsole(ProcessHandle p) {161return Platform.isWindows() && p.info().command().orElse("").endsWith("C:\\Windows\\System32\\conhost.exe");162}163164/**165* Return true if the ProcessHandle is NOT a Windows i586 conhost.exe process.166*167* @param p the processHandle of the Process168* @return Return true if the ProcessHandle is NOT for a Windows i586 conhost.exe process169*/170static boolean isNotWindowsConsole(ProcessHandle p) {171return !isWindowsConsole(p);172}173174/**175* Print a formatted string to System.out.176* @param format the format177* @param args the argument array178*/179static void printf(String format, Object... args) {180String s = String.format(format, args);181System.out.print(s);182}183184/**185* Print information about a process.186* Prints the pid, if it is alive, and information about the process.187* @param ph the processHandle at the top188*/189static void printProcess(ProcessHandle ph) {190printProcess(ph, "");191}192193/**194* Print information about a process.195* Prints the pid, if it is alive, and information about the process.196* @param ph the processHandle at the top197* @param prefix the String to prefix the output with198*/199static void printProcess(ProcessHandle ph, String prefix) {200printf("%spid %s, alive: %s; parent: %s, %s%n", prefix,201ph.pid(), ph.isAlive(), ph.parent(), ph.info());202}203204/**205* Print the process hierarchy as visible via ProcessHandle.206* Prints the pid, if it is alive, and information about the process.207* @param ph the processHandle at the top208* @param prefix the String to prefix the output with209*/210static void printDeep(ProcessHandle ph, String prefix) {211printProcess(ph, prefix);212ph.children().forEach(p -> printDeep(p, prefix + " "));213}214215/**216* Use the native command to list the active processes.217*/218static void logTaskList() {219String[] windowsArglist = {"tasklist.exe", "/v"};220String[] unixArglist = {"ps", "-ef"};221222String[] argList = null;223if (Platform.isWindows()) {224argList = windowsArglist;225} else if (Platform.isLinux() || Platform.isOSX()) {226argList = unixArglist;227} else {228return;229}230231ProcessBuilder pb = new ProcessBuilder(argList);232pb.inheritIO();233try {234Process proc = pb.start();235proc.waitFor();236} catch (IOException | InterruptedException ex) {237ex.printStackTrace();238}239}240}241242243