code: void monitorChild() {
      Process proc = childProc;
      if (proc == null) {
        // Process may have already been disposed of, e.g. by calling kill().
        return;
      }
  
      while (proc.isAlive()) {
        try {
          proc.waitFor();
        } catch (Exception e) {
          LOG.log(Level.WARNING, "Exception waiting for child process to exit.", e);
        }
      }
  
      synchronized (this) {
        if (isDisposed()) {
          return;
        }
  
        int ec;
        try {
          ec = proc.exitValue();
        } catch (Exception e) {
          LOG.log(Level.WARNING, "Exception getting child process exit code, assuming failure.", e);
          ec = 1;
        }
  
        if (ec != 0) {
          State currState = getState();
          // Override state with failure if the current state is not final, or is success.
          if (!currState.isFinal() || currState == State.FINISHED) {
            setState(State.FAILED, true);
          }
        }
  
        dispose();
      }
    }
docs: Wait for the child process to exit and update the handle's state if necessary, according to
  the exit code.