code: @Override
    public void run() {
  
      this.stateLock.lock();
  
      try {
  
        if (this.state != RunnableProcessState.INIT) {
          throw new IllegalStateException("The RunnableProcess can't be reused");
        }
  
        // Setup the stdout and stderr destinations.
        final File errFile = new File(folder, standardErrorFileName);
        final File outFile = new File(folder, standardOutFileName);
  
        // Launch the process
        try {
  
          LOG.log(Level.FINEST,
              "Launching process \"{0}\"\nSTDERR can be found in {1}\nSTDOUT can be found in {2}",
              new Object[] {this.id, errFile.getAbsolutePath(), outFile.getAbsolutePath()});
  
          this.process = new ProcessBuilder()
              .command(this.command)
              .directory(this.folder)
              .redirectError(errFile)
              .redirectOutput(outFile)
              .start();
  
          this.setState(RunnableProcessState.RUNNING);
          this.processObserver.onProcessStarted(this.id);
  
        } catch (final IOException ex) {
          LOG.log(Level.SEVERE, "Unable to spawn process " + this.id + " with command " + this.command, ex);
        }
  
      } finally {
        this.stateLock.unlock();
      }
  
      try {
  
        // Wait for its completion
        LOG.log(Level.FINER, "Wait for process completion: {0}", this.id);
        final int returnValue = this.process.waitFor();
        this.processObserver.onProcessExit(this.id, returnValue);
  
        this.stateLock.lock();
        try {
          this.setState(RunnableProcessState.ENDED);
          this.doneCond.signalAll();
        } finally {
          this.stateLock.unlock();
        }
  
        LOG.log(Level.FINER, "Process \"{0}\" returned {1}", new Object[] {this.id, returnValue});
  
      } catch (final InterruptedException ex) {
        LOG.log(Level.SEVERE,
            "Interrupted while waiting for the process \"{0}\" to complete. Exception: {1}",
            new Object[] {this.id, ex});
      }
    }
docs: Runs the configured process.
  @throws IllegalStateException if the process is already running or has been running before.