1 /* 2 * Copyright (c) 2013, 2015, 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.test.lib; 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.util.ArrayList; 31 import java.util.Collections; 32 import java.util.List; 33 34 /** 35 * @deprecated This class is deprecated. Use the one from 36 * {@code <root>/test/lib/share/classes/jdk/test/lib/process} 37 */ 38 @Deprecated 39 public final class ProcessTools { 40 41 private ProcessTools() { 42 } 43 44 /** 45 * Pumps stdout and stderr from running the process into a String. 46 * 47 * @param processBuilder ProcessBuilder to run. 48 * @return Output from process. 49 * @throws IOException If an I/O error occurs. 50 */ 51 public static OutputBuffer getOutput(ProcessBuilder processBuilder) throws IOException { 52 return getOutput(processBuilder.start()); 53 } 54 55 /** 56 * Pumps stdout and stderr the running process into a String. 57 * 58 * @param process Process to pump. 59 * @return Output from process. 60 * @throws IOException If an I/O error occurs. 61 */ 62 public static OutputBuffer getOutput(Process process) throws IOException { 63 ByteArrayOutputStream stderrBuffer = new ByteArrayOutputStream(); 64 ByteArrayOutputStream stdoutBuffer = new ByteArrayOutputStream(); 65 StreamPumper outPumper = new StreamPumper(process.getInputStream(), stdoutBuffer); 66 StreamPumper errPumper = new StreamPumper(process.getErrorStream(), stderrBuffer); 67 Thread outPumperThread = new Thread(outPumper); 68 Thread errPumperThread = new Thread(errPumper); 69 70 outPumperThread.setDaemon(true); 71 errPumperThread.setDaemon(true); 72 73 outPumperThread.start(); 74 errPumperThread.start(); 75 76 try { 77 process.waitFor(); 78 outPumperThread.join(); 79 errPumperThread.join(); 80 } catch (InterruptedException e) { 81 Thread.currentThread().interrupt(); 82 return null; 83 } 84 85 return new OutputBuffer(stdoutBuffer.toString(), stderrBuffer.toString()); 86 } 87 88 /** 89 * Get the process id of the current running Java process 90 * 91 * @return Process id 92 */ 93 public static long getProcessId() throws Exception { 94 return ProcessHandle.current().getPid(); 95 } 96 97 /** 98 * Gets the array of strings containing input arguments passed to the VM 99 * 100 * @return arguments 101 */ 102 public static String[] getVmInputArgs() { 103 RuntimeMXBean runtime = ManagementFactory.getRuntimeMXBean(); 104 List<String> args = runtime.getInputArguments(); 105 return args.toArray(new String[args.size()]); 106 } 107 108 /** 109 * Get platform specific VM arguments (e.g. -d64 on 64bit Solaris) 110 * 111 * @return String[] with platform specific arguments, empty if there are none 112 */ 113 public static String[] getPlatformSpecificVMArgs() { 114 115 if (Platform.is64bit() && Platform.isSolaris()) { 116 return new String[] { "-d64" }; 117 } 118 119 return new String[] {}; 120 } 121 122 /** 123 * Create ProcessBuilder using the java launcher from the jdk to be tested and 124 * with any platform specific arguments prepended 125 */ 126 public static ProcessBuilder createJavaProcessBuilder(String... command) throws Exception { 127 return createJavaProcessBuilder(false, command); 128 } 129 130 public static ProcessBuilder createJavaProcessBuilder(boolean addTestVmAndJavaOptions, String... command) throws Exception { 131 String javapath = JDKToolFinder.getJDKTool("java"); 132 133 ArrayList<String> args = new ArrayList<>(); 134 args.add(javapath); 135 Collections.addAll(args, getPlatformSpecificVMArgs()); 136 137 args.add("-cp"); 138 args.add(System.getProperty("java.class.path")); 139 140 if (addTestVmAndJavaOptions) { 141 Collections.addAll(args, Utils.getTestJavaOpts()); 142 } 143 144 Collections.addAll(args, command); 145 146 // Reporting 147 StringBuilder cmdLine = new StringBuilder(); 148 for (String cmd : args) { 149 cmdLine.append(cmd).append(' '); 150 } 151 System.out.println("Command line: [" + cmdLine.toString() + "]"); 152 153 return new ProcessBuilder(args.toArray(new String[args.size()])); 154 } 155 156 /** 157 * Executes a test jvm process, waits for it to finish and returns the process output. 158 * The default jvm options from jtreg, test.vm.opts and test.java.opts, are added. 159 * The java from the test.jdk is used to execute the command. 160 * 161 * The command line will be like: 162 * {test.jdk}/bin/java {test.vm.opts} {test.java.opts} cmds 163 * 164 * @param cmds User specifed arguments. 165 * @return The output from the process. 166 */ 167 public static OutputAnalyzer executeTestJvm(String... cmds) throws Throwable { 168 ProcessBuilder pb = createJavaProcessBuilder(Utils.addTestJavaOpts(cmds)); 169 return executeProcess(pb); 170 } 171 172 /** 173 * Executes a test jvm process, waits for it to finish and returns the process output. 174 * The default jvm options from the test's run command, jtreg, test.vm.opts and test.java.opts, are added. 175 * The java from the test.jdk is used to execute the command. 176 * 177 * The command line will be like: 178 * {test.jdk}/bin/java {test.fromRun.opts} {test.vm.opts} {test.java.opts} cmds 179 * 180 * @param cmds User specifed arguments. 181 * @return The output from the process. 182 */ 183 public static OutputAnalyzer executeTestJvmAllArgs(String... cmds) throws Throwable { 184 List<String> argsList = new ArrayList<>(); 185 String[] testArgs = getVmInputArgs(); 186 Collections.addAll(argsList, testArgs); 187 Collections.addAll(argsList, Utils.addTestJavaOpts(cmds)); 188 ProcessBuilder pb = createJavaProcessBuilder(argsList.toArray(new String[argsList.size()])); 189 return executeProcess(pb); 190 } 191 192 /** 193 * Executes a process, waits for it to finish and returns the process output. 194 * The process will have exited before this method returns. 195 * @param pb The ProcessBuilder to execute. 196 * @return The {@linkplain OutputAnalyzer} instance wrapping the process. 197 */ 198 public static OutputAnalyzer executeProcess(ProcessBuilder pb) throws Exception { 199 OutputAnalyzer output = null; 200 Process p = null; 201 boolean failed = false; 202 try { 203 p = pb.start(); 204 output = new OutputAnalyzer(p); 205 p.waitFor(); 206 207 return output; 208 } catch (Throwable t) { 209 if (p != null) { 210 p.destroyForcibly().waitFor(); 211 } 212 213 failed = true; 214 System.out.println("executeProcess() failed: " + t); 215 throw t; 216 } finally { 217 if (failed) { 218 System.err.println(getProcessLog(pb, output)); 219 } 220 } 221 } 222 223 /** 224 * Executes a process, waits for it to finish and returns the process output. 225 * @param cmds The command line to execute. 226 * @return The output from the process. 227 */ 228 public static OutputAnalyzer executeProcess(String... cmds) throws Throwable { 229 return executeProcess(new ProcessBuilder(cmds)); 230 } 231 232 /** 233 * Used to log command line, stdout, stderr and exit code from an executed process. 234 * @param pb The executed process. 235 * @param output The output from the process. 236 */ 237 public static String getProcessLog(ProcessBuilder pb, OutputAnalyzer output) { 238 String stderr = output == null ? "null" : output.getStderr(); 239 String stdout = output == null ? "null" : output.getStdout(); 240 String exitValue = output == null ? "null": Integer.toString(output.getExitValue()); 241 StringBuilder logMsg = new StringBuilder(); 242 final String nl = System.getProperty("line.separator"); 243 logMsg.append("--- ProcessLog ---" + nl); 244 logMsg.append("cmd: " + getCommandLine(pb) + nl); 245 logMsg.append("exitvalue: " + exitValue + nl); 246 logMsg.append("stderr: " + stderr + nl); 247 logMsg.append("stdout: " + stdout + nl); 248 return logMsg.toString(); 249 } 250 251 /** 252 * @return The full command line for the ProcessBuilder. 253 */ 254 public static String getCommandLine(ProcessBuilder pb) { 255 if (pb == null) { 256 return "null"; 257 } 258 StringBuilder cmd = new StringBuilder(); 259 for (String s : pb.command()) { 260 cmd.append(s).append(" "); 261 } 262 return cmd.toString().trim(); 263 } 264 }