public CompletableFuture<Process> onExit ()

Returns a CompletableFuture<Process> for the termination of the Process. The java.util.concurrent.CompletableFuture provides the ability to trigger dependent functions or actions that may be run synchronously or asynchronously upon process termination. When the process has terminated the CompletableFuture is completed regardless of the exit status of the process.

Calling onExit().get() waits for the process to terminate and returns the Process. The future can be used to check if the process is done or to wait for it to terminate. Cancelling the CompletableFuture does not affect the Process.

Processes returned from ProcessBuilder.start override the default implementation to provide an efficient mechanism to wait for process exit.

Returns:  a new CompletableFuture<Process> for the Process

Since:  9

@apiNote Using onExit is an alternative to waitFor that enables both additional concurrency and convenient access to the result of the Process. Lambda expressions can be used to evaluate the result of the Process execution. If there is other processing to be done before the value is used then onExit is a convenient mechanism to free the current thread and block only if and when the value is needed.
For example, launching a process to compare two files and get a boolean if they are identical:

    Process p = new ProcessBuilder("cmp", "f1", "f2").start();
    Future<Boolean> identical = p.onExit().thenApply(p1 -> p1.exitValue() == 0);
    ...
    if (identical.get()) { ... 
 }

@implSpec This implementation executes waitFor() in a separate thread repeatedly until it returns successfully. If the execution of waitFor is interrupted, the thread's interrupt status is preserved.

When waitFor() returns successfully the CompletableFuture is completed regardless of the exit status of the process. This implementation may consume a lot of memory for thread stacks if a large number of processes are waited for concurrently.

External implementations should override this method and provide a more efficient implementation. For example, to delegate to the underlying process, it can do the following:


    public CompletableFuture<Process> onExit() {
       return delegate.onExit().thenApply(p -> this);
    
 }

@apiNote The process may be observed to have terminated with isAlive before the ComputableFuture is completed and dependent actions are invoked.