81 * <p>Subclasses of Process should override the {@link #onExit()} and |
81 * <p>Subclasses of Process should override the {@link #onExit()} and |
82 * {@link #toHandle()} methods to provide a fully functional Process including the |
82 * {@link #toHandle()} methods to provide a fully functional Process including the |
83 * {@link #getPid() process id}, |
83 * {@link #getPid() process id}, |
84 * {@link #info() information about the process}, |
84 * {@link #info() information about the process}, |
85 * {@link #children() direct children}, and |
85 * {@link #children() direct children}, and |
86 * {@link #allChildren() direct and indirect children} of the process. |
86 * {@link #descendants() direct children plus descendants of those children} of the process. |
87 * Delegating to the underlying Process or ProcessHandle is typically |
87 * Delegating to the underlying Process or ProcessHandle is typically |
88 * easiest and most efficient. |
88 * easiest and most efficient. |
89 * |
89 * |
90 * @since 1.0 |
90 * @since 1.0 |
91 */ |
91 */ |
349 /** |
349 /** |
350 * Returns a {@code CompletableFuture<Process>} for the termination of the Process. |
350 * Returns a {@code CompletableFuture<Process>} for the termination of the Process. |
351 * The {@link java.util.concurrent.CompletableFuture} provides the ability |
351 * The {@link java.util.concurrent.CompletableFuture} provides the ability |
352 * to trigger dependent functions or actions that may be run synchronously |
352 * to trigger dependent functions or actions that may be run synchronously |
353 * or asynchronously upon process termination. |
353 * or asynchronously upon process termination. |
354 * When the process terminates the CompletableFuture is |
354 * When the process has terminated the CompletableFuture is |
355 * {@link java.util.concurrent.CompletableFuture#complete completed} regardless |
355 * {@link java.util.concurrent.CompletableFuture#complete completed} regardless |
356 * of the exit status of the process. |
356 * of the exit status of the process. |
357 * <p> |
357 * <p> |
358 * Calling {@code onExit().get()} waits for the process to terminate and returns |
358 * Calling {@code onExit().get()} waits for the process to terminate and returns |
359 * the Process. The future can be used to check if the process is |
359 * the Process. The future can be used to check if the process is |
360 * {@link java.util.concurrent.CompletableFuture#isDone done} or to |
360 * {@link java.util.concurrent.CompletableFuture#isDone done} or to |
361 * {@link java.util.concurrent.CompletableFuture#get() wait} for it to terminate. |
361 * {@link java.util.concurrent.CompletableFuture#get() wait} for it to terminate. |
362 * {@link java.util.concurrent.CompletableFuture#cancel(boolean) Cancelling} |
362 * {@link java.util.concurrent.CompletableFuture#cancel(boolean) Cancelling} |
363 * the CompletableFuture does not affect the Process. |
363 * the CompletableFuture does not affect the Process. |
364 * <p> |
|
365 * If the process is {@link #isAlive not alive} the {@link CompletableFuture} |
|
366 * returned has been {@link java.util.concurrent.CompletableFuture#complete completed}. |
|
367 * <p> |
364 * <p> |
368 * Processes returned from {@link ProcessBuilder#start} override the |
365 * Processes returned from {@link ProcessBuilder#start} override the |
369 * default implementation to provide an efficient mechanism to wait |
366 * default implementation to provide an efficient mechanism to wait |
370 * for process exit. |
367 * for process exit. |
371 * |
368 * |
462 * @implSpec |
462 * @implSpec |
463 * This implementation throws an instance of |
463 * This implementation throws an instance of |
464 * {@link java.lang.UnsupportedOperationException} and performs no other action. |
464 * {@link java.lang.UnsupportedOperationException} and performs no other action. |
465 * Subclasses should override this method to provide a ProcessHandle for the |
465 * Subclasses should override this method to provide a ProcessHandle for the |
466 * process. The methods {@link #getPid}, {@link #info}, {@link #children}, |
466 * process. The methods {@link #getPid}, {@link #info}, {@link #children}, |
467 * and {@link #allChildren}, unless overridden, operate on the ProcessHandle. |
467 * and {@link #descendants}, unless overridden, operate on the ProcessHandle. |
468 * |
468 * |
469 * @return Returns a ProcessHandle for the Process |
469 * @return Returns a ProcessHandle for the Process |
470 * @throws UnsupportedOperationException if the Process implementation |
470 * @throws UnsupportedOperationException if the Process implementation |
471 * does not support this operation |
471 * does not support this operation |
472 * @throws SecurityException if a security manager has been installed and |
472 * @throws SecurityException if a security manager has been installed and |
479 } |
479 } |
480 |
480 |
481 /** |
481 /** |
482 * Returns a snapshot of information about the process. |
482 * Returns a snapshot of information about the process. |
483 * |
483 * |
484 * <p> An {@link ProcessHandle.Info} instance has various accessor methods |
484 * <p> A {@link ProcessHandle.Info} instance has accessor methods |
485 * that return information about the process, if the process is alive and |
485 * that return information about the process if it is available. |
486 * the information is available, otherwise {@code null} is returned. |
|
487 * |
486 * |
488 * @implSpec |
487 * @implSpec |
489 * This implementation returns information about the process as: |
488 * This implementation returns information about the process as: |
490 * {@link #toHandle toHandle().info()}. |
489 * {@link #toHandle toHandle().info()}. |
491 * |
490 * |
522 public Stream<ProcessHandle> children() { |
521 public Stream<ProcessHandle> children() { |
523 return toHandle().children(); |
522 return toHandle().children(); |
524 } |
523 } |
525 |
524 |
526 /** |
525 /** |
527 * Returns a snapshot of the direct and indirect children of the process. |
526 * Returns a snapshot of the descendants of the process. |
528 * An indirect child is one whose parent is either a direct child or |
527 * The descendants of a process are the children of the process |
529 * another indirect child. |
528 * plus the descendants of those children, recursively. |
530 * Typically, a process that is {@link #isAlive not alive} has no children. |
529 * Typically, a process that is {@link #isAlive not alive} has no children. |
531 * <p> |
530 * <p> |
532 * <em>Note that processes are created and terminate asynchronously. |
531 * <em>Note that processes are created and terminate asynchronously. |
533 * There is no guarantee that a process is {@link #isAlive alive}. |
532 * There is no guarantee that a process is {@link #isAlive alive}. |
534 * </em> |
533 * </em> |
535 * |
534 * |
536 * @implSpec |
535 * @implSpec |
537 * This implementation returns all children as: |
536 * This implementation returns all children as: |
538 * {@link #toHandle toHandle().allChildren()}. |
537 * {@link #toHandle toHandle().descendants()}. |
539 * |
538 * |
540 * @return a sequential Stream of ProcessHandles for processes that are |
539 * @return a sequential Stream of ProcessHandles for processes that |
541 * direct and indirect children of the process |
540 * are descendants of the process |
542 * @throws UnsupportedOperationException if the Process implementation |
541 * @throws UnsupportedOperationException if the Process implementation |
543 * does not support this operation |
542 * does not support this operation |
544 * @throws SecurityException if a security manager has been installed and |
543 * @throws SecurityException if a security manager has been installed and |
545 * it denies RuntimePermission("manageProcess") |
544 * it denies RuntimePermission("manageProcess") |
546 * @since 1.9 |
545 * @since 1.9 |
547 */ |
546 */ |
548 public Stream<ProcessHandle> allChildren() { |
547 public Stream<ProcessHandle> descendants() { |
549 return toHandle().allChildren(); |
548 return toHandle().descendants(); |
550 } |
549 } |
551 |
550 |
552 |
551 |
553 } |
552 } |