1 /* 2 * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 package jdk.testlibrary; 25 26 import java.io.ByteArrayOutputStream; 27 import java.io.IOException; 28 import java.lang.management.ManagementFactory; 29 import java.lang.management.RuntimeMXBean; 30 import java.lang.reflect.Field; 31 import java.lang.reflect.Method; 32 import java.util.ArrayList; 33 import java.util.Collections; 34 35 import sun.management.VMManagement; 36 37 public final class ProcessTools { 38 39 private ProcessTools() { 40 } 41 42 /** 43 * Pumps stdout and stderr from running the process into a String. 44 * 45 * @param processHandler 46 * ProcessHandler to run. 47 * @return Output from process. 48 * @throws IOException 49 * If an I/O error occurs. 50 */ 51 public static OutputBuffer getOutput(ProcessBuilder processBuilder) 52 throws IOException { 53 return getOutput(processBuilder.start()); 54 } 55 56 /** 57 * Pumps stdout and stderr the running process into a String. 58 * 59 * @param process 60 * Process to pump. 61 * @return Output from process. 62 * @throws IOException 63 * If an I/O error occurs. 64 */ 65 public static OutputBuffer getOutput(Process process) throws IOException { 66 ByteArrayOutputStream stderrBuffer = new ByteArrayOutputStream(); 67 ByteArrayOutputStream stdoutBuffer = new ByteArrayOutputStream(); 68 StreamPumper outPumper = new StreamPumper(process.getInputStream(), 69 stdoutBuffer); 70 StreamPumper errPumper = new StreamPumper(process.getErrorStream(), 71 stderrBuffer); 72 Thread outPumperThread = new Thread(outPumper); 73 Thread errPumperThread = new Thread(errPumper); 74 75 outPumperThread.setDaemon(true); 76 errPumperThread.setDaemon(true); 77 78 outPumperThread.start(); 79 errPumperThread.start(); 80 81 try { 82 process.waitFor(); 83 outPumperThread.join(); 84 errPumperThread.join(); 85 } catch (InterruptedException e) { 86 Thread.currentThread().interrupt(); 87 return null; 88 } 89 90 return new OutputBuffer(stdoutBuffer.toString(), 91 stderrBuffer.toString()); 92 } 93 94 /** 95 * Get the process id of the current running Java process 96 * 97 * @return Process id 98 */ 99 public static int getProcessId() throws Exception { 100 101 // Get the current process id using a reflection hack 102 RuntimeMXBean runtime = ManagementFactory.getRuntimeMXBean(); 103 Field jvm = runtime.getClass().getDeclaredField("jvm"); 104 105 jvm.setAccessible(true); 106 VMManagement mgmt = (sun.management.VMManagement) jvm.get(runtime); 107 108 Method pid_method = mgmt.getClass().getDeclaredMethod("getProcessId"); 109 110 pid_method.setAccessible(true); 111 112 int pid = (Integer) pid_method.invoke(mgmt); 113 114 return pid; 115 } 116 117 /** 118 * Get platform specific VM arguments (e.g. -d64 on 64bit Solaris) 119 * 120 * @return String[] with platform specific arguments, empty if there are 121 * none 122 */ 123 public static String[] getPlatformSpecificVMArgs() { 124 String osName = System.getProperty("os.name"); 125 String dataModel = System.getProperty("sun.arch.data.model"); 126 127 if (osName.equals("SunOS") && dataModel.equals("64")) { 128 return new String[] { "-d64" }; 129 } 130 131 return new String[] {}; 132 } 133 134 /** 135 * Create ProcessBuilder using the java launcher from the jdk to be tested 136 * and with any platform specific arguments prepended 137 */ 138 public static ProcessBuilder createJavaProcessBuilder(String... command) 139 throws Exception { 140 String javapath = JdkFinder.getJavaLauncher(false); 141 142 ArrayList<String> args = new ArrayList<>(); 143 args.add(javapath); 144 Collections.addAll(args, getPlatformSpecificVMArgs()); 145 Collections.addAll(args, command); 146 147 return new ProcessBuilder(args.toArray(new String[args.size()])); 148 149 } 150 151 }