alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Java example source code file (ProcessTools.java)

This example Java source code file (ProcessTools.java) is included in the alvinalexander.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Learn more about this Java project at its project page.

Java - Java tags/keywords

bytearrayoutputstream, future, interruptedexception, ioexception, lineforwarder, management, outputanalyzer, phaser, processbuilder, reflection, stacktraceelement, streampumper, string, stringbuilder, threading, threads, throwable, timeoutexception, util

The ProcessTools.java Java example source code

/*
 * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package jdk.testlibrary;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.lang.management.ManagementFactory;
import java.lang.management.RuntimeMXBean;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.Phaser;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.function.Predicate;

import sun.management.VMManagement;

public final class ProcessTools {
    private static final class LineForwarder extends StreamPumper.LinePump {
        private final PrintStream ps;
        private final String prefix;
        LineForwarder(String prefix, PrintStream os) {
            this.ps = os;
            this.prefix = prefix;
        }
        @Override
        protected void processLine(String line) {
            ps.println("[" + prefix + "] " + line);
        }
    }

    private ProcessTools() {
    }

    /**
     * <p>Starts a process from its builder.

* <span>The default redirects of STDOUT and STDERR are started * @param name The process name * @param processBuilder The process builder * @return Returns the initialized process * @throws IOException */ public static Process startProcess(String name, ProcessBuilder processBuilder) throws IOException { Process p = null; try { p = startProcess(name, processBuilder, null, -1, TimeUnit.NANOSECONDS); } catch (InterruptedException | TimeoutException e) { // can't ever happen } return p; } /** * <p>Starts a process from its builder.

* <span>The default redirects of STDOUT and STDERR are started * <p> * It is possible to wait for the process to get to a warmed-up state * via {@linkplain Predicate} condition on the STDOUT * </p> * @param name The process name * @param processBuilder The process builder * @param linePredicate The {@linkplain Predicate} to use on the STDOUT * Used to determine the moment the target app is * properly warmed-up. * It can be null - in that case the warmup is skipped. * @param timeout The timeout for the warmup waiting * @param unit The timeout {@linkplain TimeUnit} * @return Returns the initialized {@linkplain Process} * @throws IOException * @throws InterruptedException * @throws TimeoutException */ public static Process startProcess(String name, ProcessBuilder processBuilder, final Predicate<String> linePredicate, long timeout, TimeUnit unit) throws IOException, InterruptedException, TimeoutException { Process p = processBuilder.start(); StreamPumper stdout = new StreamPumper(p.getInputStream()); StreamPumper stderr = new StreamPumper(p.getErrorStream()); stdout.addPump(new LineForwarder(name, System.out)); stderr.addPump(new LineForwarder(name, System.err)); final Phaser phs = new Phaser(1); if (linePredicate != null) { stdout.addPump(new StreamPumper.LinePump() { @Override protected void processLine(String line) { if (linePredicate.test(line)) { if (phs.getRegisteredParties() > 0) { phs.arriveAndDeregister(); } } } }); } Future<Void> stdoutTask = stdout.process(); Future<Void> stderrTask = stderr.process(); try { if (timeout > -1) { phs.awaitAdvanceInterruptibly(0, timeout, unit); } } catch (TimeoutException | InterruptedException e) { System.err.println("Failed to start a process (thread dump follows)"); for(Map.Entry<Thread, StackTraceElement[]> s : Thread.getAllStackTraces().entrySet()) { printStack(s.getKey(), s.getValue()); } stdoutTask.cancel(true); stderrTask.cancel(true); throw e; } return p; } /** * Pumps stdout and stderr from running the process into a String. * * @param processBuilder * ProcessHandler to run. * @return Output from process. * @throws IOException * If an I/O error occurs. */ public static OutputBuffer getOutput(ProcessBuilder processBuilder) throws IOException { return getOutput(processBuilder.start()); } /** * Pumps stdout and stderr the running process into a String. * * @param process * Process to pump. * @return Output from process. * @throws IOException * If an I/O error occurs. */ public static OutputBuffer getOutput(Process process) throws IOException { ByteArrayOutputStream stderrBuffer = new ByteArrayOutputStream(); ByteArrayOutputStream stdoutBuffer = new ByteArrayOutputStream(); StreamPumper outPumper = new StreamPumper(process.getInputStream(), stdoutBuffer); StreamPumper errPumper = new StreamPumper(process.getErrorStream(), stderrBuffer); Future<Void> outTask = outPumper.process(); Future<Void> errTask = errPumper.process(); try { process.waitFor(); outTask.get(); errTask.get(); } catch (InterruptedException e) { Thread.currentThread().interrupt(); return null; } catch (ExecutionException e) { throw new IOException(e); } return new OutputBuffer(stdoutBuffer.toString(), stderrBuffer.toString()); } /** * Get the process id of the current running Java process * * @return Process id */ public static int getProcessId() throws Exception { // Get the current process id using a reflection hack RuntimeMXBean runtime = ManagementFactory.getRuntimeMXBean(); Field jvm = runtime.getClass().getDeclaredField("jvm"); jvm.setAccessible(true); VMManagement mgmt = (sun.management.VMManagement) jvm.get(runtime); Method pid_method = mgmt.getClass().getDeclaredMethod("getProcessId"); pid_method.setAccessible(true); int pid = (Integer) pid_method.invoke(mgmt); return pid; } /** * Get platform specific VM arguments (e.g. -d64 on 64bit Solaris) * * @return String[] with platform specific arguments, empty if there are * none */ public static String[] getPlatformSpecificVMArgs() { String osName = System.getProperty("os.name"); String dataModel = System.getProperty("sun.arch.data.model"); if (osName.equals("SunOS") && dataModel.equals("64")) { return new String[] { "-d64" }; } return new String[] {}; } /** * Create ProcessBuilder using the java launcher from the jdk to be tested * and with any platform specific arguments prepended */ public static ProcessBuilder createJavaProcessBuilder(String... command) throws Exception { String javapath = JDKToolFinder.getJDKTool("java"); ArrayList<String> args = new ArrayList<>(); args.add(javapath); Collections.addAll(args, getPlatformSpecificVMArgs()); Collections.addAll(args, command); // Reporting StringBuilder cmdLine = new StringBuilder(); for (String cmd : args) cmdLine.append(cmd).append(' '); System.out.println("Command line: [" + cmdLine.toString() + "]"); return new ProcessBuilder(args.toArray(new String[args.size()])); } private static void printStack(Thread t, StackTraceElement[] stack) { System.out.println("\t" + t + " stack: (length = " + stack.length + ")"); if (t != null) { for (StackTraceElement stack1 : stack) { System.out.println("\t" + stack1); } System.out.println(); } } /** * Executes a test jvm process, waits for it to finish and returns the process output. * The default jvm options from jtreg, test.vm.opts and test.java.opts, are added. * The java from the test.jdk is used to execute the command. * * The command line will be like: * {test.jdk}/bin/java {test.vm.opts} {test.java.opts} cmds * * @param cmds User specifed arguments. * @return The output from the process. */ public static OutputAnalyzer executeTestJvm(String... cmds) throws Throwable { ProcessBuilder pb = createJavaProcessBuilder(Utils.addTestJavaOpts(cmds)); return executeProcess(pb); } /** * Executes a process, waits for it to finish and returns the process output. * @param pb The ProcessBuilder to execute. * @return The output from the process. */ public static OutputAnalyzer executeProcess(ProcessBuilder pb) throws Throwable { OutputAnalyzer output = null; try { output = new OutputAnalyzer(pb.start()); return output; } catch (Throwable t) { System.out.println("executeProcess() failed: " + t); throw t; } finally { System.out.println(getProcessLog(pb, output)); } } /** * Executes a process, waits for it to finish and returns the process output. * @param cmds The command line to execute. * @return The output from the process. */ public static OutputAnalyzer executeProcess(String... cmds) throws Throwable { return executeProcess(new ProcessBuilder(cmds)); } /** * Used to log command line, stdout, stderr and exit code from an executed process. * @param pb The executed process. * @param output The output from the process. */ public static String getProcessLog(ProcessBuilder pb, OutputAnalyzer output) { String stderr = output == null ? "null" : output.getStderr(); String stdout = output == null ? "null" : output.getStdout(); String exitValue = output == null ? "null": Integer.toString(output.getExitValue()); StringBuilder logMsg = new StringBuilder(); final String nl = System.getProperty("line.separator"); logMsg.append("--- ProcessLog ---" + nl); logMsg.append("cmd: " + getCommandLine(pb) + nl); logMsg.append("exitvalue: " + exitValue + nl); logMsg.append("stderr: " + stderr + nl); logMsg.append("stdout: " + stdout + nl); return logMsg.toString(); } /** * @return The full command line for the ProcessBuilder. */ public static String getCommandLine(ProcessBuilder pb) { if (pb == null) { return "null"; } StringBuilder cmd = new StringBuilder(); for (String s : pb.command()) { cmd.append(s).append(" "); } return cmd.toString().trim(); } }

Other Java examples (source code examples)

Here is a short list of links related to this Java ProcessTools.java source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.