Example #1
0
  /**
   * 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());
  }
Example #2
0
  /**
   * Starts a process from its builder. <span>The default redirects of STDOUT and STDERR are
   * started</span>
   *
   * <p>It is possible to wait for the process to get to a warmed-up state via {@linkplain
   * Predicate} condition on the STDOUT
   *
   * @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));
    CountDownLatch latch = new CountDownLatch(1);
    if (linePredicate != null) {
      StreamPumper.LinePump pump =
          new StreamPumper.LinePump() {
            @Override
            protected void processLine(String line) {
              if (latch.getCount() > 0 && linePredicate.test(line)) {
                latch.countDown();
              }
            }
          };
      stdout.addPump(pump);
      stderr.addPump(pump);
    }
    Future<Void> stdoutTask = stdout.process();
    Future<Void> stderrTask = stderr.process();

    try {
      if (timeout > -1) {
        long realTimeout = Math.round(timeout * Utils.TIMEOUT_FACTOR);
        if (!latch.await(realTimeout, unit)) {
          throw new TimeoutException();
        }
      }
    } 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;
  }