code: private static Thread createAsyncStreamThread(final InputStream input,
                                                  final StringBuilder processOutputStringBuilder,
                                                  final boolean isVerbose) {
      Thread thread = new Thread() {
        @Override
        public void run() {
          // do not buffer
          LOG.log(Level.FINE, "Process output (stdout+stderr):");
          BufferedReader reader = new BufferedReader(new InputStreamReader(input), 1);
          while (true) {
            String line = null;
            try {
              line = reader.readLine();
            } catch (IOException e) {
              LOG.log(Level.SEVERE, "Error when reading line from subprocess", e);
            }
            if (line == null) {
              break;
            } else {
              if (isVerbose) {
                System.err.println(line);
              }
              if (processOutputStringBuilder != null) {
                processOutputStringBuilder.append(line);
              }
            }
          }
          try {
            input.close();
          } catch (IOException e) {
            LOG.log(Level.WARNING, "Failed to close the input stream", e);
          }
        }
      };
      thread.setDaemon(true);
      return thread;
    }
docs: Read and print line from input, and save each line in a string builder
  line read from input is printed to stderr directly instead of using LOG (which will
  add redundant timestamp and class name info).
  
  This method does not start the thread. Instead, caller should start this thread.
  
  @param input input stream
  @param processOutputStringBuilder string builder used to save input lines
  @return thread