< prev index next >

jdk/src/java.base/share/classes/java/lang/Process.java

Print this page




 287 
 288     /**
 289      * Returns {@code true} if the implementation of {@link #destroy} is to
 290      * normally terminate the process,
 291      * Returns {@code false} if the implementation of {@code destroy}
 292      * forcibly and immediately terminates the process.
 293      * <p>
 294      * Invoking this method on {@code Process} objects returned by
 295      * {@link ProcessBuilder#start} and {@link Runtime#exec} return
 296      * {@code true} or {@code false} depending on the platform implementation.
 297      *
 298      * @implSpec
 299      * This implementation throws an instance of
 300      * {@link java.lang.UnsupportedOperationException} and performs no other action.
 301      *
 302      * @return {@code true} if the implementation of {@link #destroy} is to
 303      *         normally terminate the process;
 304      *         otherwise, {@link #destroy} forcibly terminates the process
 305      * @throws UnsupportedOperationException if the Process implementation
 306      *         does not support this operation
 307      * @since 1.9
 308      */
 309     public boolean supportsNormalTermination() {
 310         throw new UnsupportedOperationException(this.getClass()
 311                 + ".supportsNormalTermination() not supported" );
 312     }
 313 
 314     /**
 315      * Tests whether the process represented by this {@code Process} is
 316      * alive.
 317      *
 318      * @return {@code true} if the process represented by this
 319      *         {@code Process} object has not yet terminated.
 320      * @since 1.8
 321      */
 322     public boolean isAlive() {
 323         try {
 324             exitValue();
 325             return false;
 326         } catch(IllegalThreadStateException e) {
 327             return true;
 328         }
 329     }
 330 
 331     /**
 332      * Returns the native process ID of the process.
 333      * The native process ID is an identification number that the operating
 334      * system assigns to the process.
 335      *
 336      * @implSpec
 337      * The implementation of this method returns the process id as:
 338      * {@link #toHandle toHandle().getPid()}.
 339      *
 340      * @return the native process id of the process
 341      * @throws UnsupportedOperationException if the Process implementation
 342      *         does not support this operation
 343      * @since 1.9
 344      */
 345     public long getPid() {
 346         return toHandle().getPid();
 347     }
 348 
 349     /**
 350      * Returns a {@code CompletableFuture<Process>} for the termination of the Process.
 351      * The {@link java.util.concurrent.CompletableFuture} provides the ability
 352      * to trigger dependent functions or actions that may be run synchronously
 353      * or asynchronously upon process termination.
 354      * When the process has terminated the CompletableFuture is
 355      * {@link java.util.concurrent.CompletableFuture#complete completed} regardless
 356      * of the exit status of the process.
 357      * <p>
 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
 360      * {@link java.util.concurrent.CompletableFuture#isDone done} or to
 361      * {@link java.util.concurrent.CompletableFuture#get() wait} for it to terminate.
 362      * {@link java.util.concurrent.CompletableFuture#cancel(boolean) Cancelling}
 363      * the CompletableFuture does not affect the Process.


 392      * {@link java.util.concurrent.CompletableFuture#complete completed} regardless
 393      * of the exit status of the process.
 394      *
 395      * This implementation may consume a lot of memory for thread stacks if a
 396      * large number of processes are waited for concurrently.
 397      * <p>
 398      * External implementations should override this method and provide
 399      * a more efficient implementation. For example, to delegate to the underlying
 400      * process, it can do the following:
 401      * <pre>{@code
 402      *    public CompletableFuture<Process> onExit() {
 403      *       return delegate.onExit().thenApply(p -> this);
 404      *    }
 405      * }</pre>
 406      * @apiNote
 407      * The process may be observed to have terminated with {@link #isAlive}
 408      * before the ComputableFuture is completed and dependent actions are invoked.
 409      *
 410      * @return a new {@code CompletableFuture<Process>} for the Process
 411      *
 412      * @since 1.9
 413      */
 414     public CompletableFuture<Process> onExit() {
 415         return CompletableFuture.supplyAsync(this::waitForInternal);
 416     }
 417 
 418     /**
 419      * Wait for the process to exit by calling {@code waitFor}.
 420      * If the thread is interrupted, remember the interrupted state to
 421      * be restored before returning. Use ForkJoinPool.ManagedBlocker
 422      * so that the number of workers in case ForkJoinPool is used is
 423      * compensated when the thread blocks in waitFor().
 424      *
 425      * @return the Process
 426      */
 427     private Process waitForInternal() {
 428         boolean interrupted = false;
 429         while (true) {
 430             try {
 431                 ForkJoinPool.managedBlock(new ForkJoinPool.ManagedBlocker() {
 432                     @Override


 454     /**
 455      * Returns a ProcessHandle for the Process.
 456      *
 457      * {@code Process} objects returned by {@link ProcessBuilder#start} and
 458      * {@link Runtime#exec} implement {@code toHandle} as the equivalent of
 459      * {@link ProcessHandle#of(long) ProcessHandle.of(pid)} including the
 460      * check for a SecurityManager and {@code RuntimePermission("manageProcess")}.
 461      *
 462      * @implSpec
 463      * This implementation throws an instance of
 464      * {@link java.lang.UnsupportedOperationException} and performs no other action.
 465      * Subclasses should override this method to provide a ProcessHandle for the
 466      * process.  The methods {@link #getPid}, {@link #info}, {@link #children},
 467      * and {@link #descendants}, unless overridden, operate on the ProcessHandle.
 468      *
 469      * @return Returns a ProcessHandle for the Process
 470      * @throws UnsupportedOperationException if the Process implementation
 471      *         does not support this operation
 472      * @throws SecurityException if a security manager has been installed and
 473      *         it denies RuntimePermission("manageProcess")
 474      * @since 1.9
 475      */
 476     public ProcessHandle toHandle() {
 477         throw new UnsupportedOperationException(this.getClass()
 478                 + ".toHandle() not supported");
 479     }
 480 
 481     /**
 482      * Returns a snapshot of information about the process.
 483      *
 484      * <p> A {@link ProcessHandle.Info} instance has accessor methods
 485      * that return information about the process if it is available.
 486      *
 487      * @implSpec
 488      * This implementation returns information about the process as:
 489      * {@link #toHandle toHandle().info()}.
 490      *
 491      * @return a snapshot of information about the process, always non-null
 492      * @throws UnsupportedOperationException if the Process implementation
 493      *         does not support this operation
 494      * @since 1.9
 495      */
 496     public ProcessHandle.Info info() {
 497         return toHandle().info();
 498     }
 499 
 500     /**
 501      * Returns a snapshot of the direct children of the process.
 502      * The parent of a direct child process is the process.
 503      * Typically, a process that is {@link #isAlive not alive} has no children.
 504      * <p>
 505      * <em>Note that processes are created and terminate asynchronously.
 506      * There is no guarantee that a process is {@link #isAlive alive}.
 507      * </em>
 508      *
 509      * @implSpec
 510      * This implementation returns the direct children as:
 511      * {@link #toHandle toHandle().children()}.
 512      *
 513      * @return a sequential Stream of ProcessHandles for processes that are
 514      *         direct children of the process
 515      * @throws UnsupportedOperationException if the Process implementation
 516      *         does not support this operation
 517      * @throws SecurityException if a security manager has been installed and
 518      *         it denies RuntimePermission("manageProcess")
 519      * @since 1.9
 520      */
 521     public Stream<ProcessHandle> children() {
 522         return toHandle().children();
 523     }
 524 
 525     /**
 526      * Returns a snapshot of the descendants of the process.
 527      * The descendants of a process are the children of the process
 528      * plus the descendants of those children, recursively.
 529      * Typically, a process that is {@link #isAlive not alive} has no children.
 530      * <p>
 531      * <em>Note that processes are created and terminate asynchronously.
 532      * There is no guarantee that a process is {@link #isAlive alive}.
 533      * </em>
 534      *
 535      * @implSpec
 536      * This implementation returns all children as:
 537      * {@link #toHandle toHandle().descendants()}.
 538      *
 539      * @return a sequential Stream of ProcessHandles for processes that
 540      *         are descendants of the process
 541      * @throws UnsupportedOperationException if the Process implementation
 542      *         does not support this operation
 543      * @throws SecurityException if a security manager has been installed and
 544      *         it denies RuntimePermission("manageProcess")
 545      * @since 1.9
 546      */
 547     public Stream<ProcessHandle> descendants() {
 548         return toHandle().descendants();
 549     }
 550 
 551 
 552 }


 287 
 288     /**
 289      * Returns {@code true} if the implementation of {@link #destroy} is to
 290      * normally terminate the process,
 291      * Returns {@code false} if the implementation of {@code destroy}
 292      * forcibly and immediately terminates the process.
 293      * <p>
 294      * Invoking this method on {@code Process} objects returned by
 295      * {@link ProcessBuilder#start} and {@link Runtime#exec} return
 296      * {@code true} or {@code false} depending on the platform implementation.
 297      *
 298      * @implSpec
 299      * This implementation throws an instance of
 300      * {@link java.lang.UnsupportedOperationException} and performs no other action.
 301      *
 302      * @return {@code true} if the implementation of {@link #destroy} is to
 303      *         normally terminate the process;
 304      *         otherwise, {@link #destroy} forcibly terminates the process
 305      * @throws UnsupportedOperationException if the Process implementation
 306      *         does not support this operation
 307      * @since 9
 308      */
 309     public boolean supportsNormalTermination() {
 310         throw new UnsupportedOperationException(this.getClass()
 311                 + ".supportsNormalTermination() not supported" );
 312     }
 313 
 314     /**
 315      * Tests whether the process represented by this {@code Process} is
 316      * alive.
 317      *
 318      * @return {@code true} if the process represented by this
 319      *         {@code Process} object has not yet terminated.
 320      * @since 1.8
 321      */
 322     public boolean isAlive() {
 323         try {
 324             exitValue();
 325             return false;
 326         } catch(IllegalThreadStateException e) {
 327             return true;
 328         }
 329     }
 330 
 331     /**
 332      * Returns the native process ID of the process.
 333      * The native process ID is an identification number that the operating
 334      * system assigns to the process.
 335      *
 336      * @implSpec
 337      * The implementation of this method returns the process id as:
 338      * {@link #toHandle toHandle().getPid()}.
 339      *
 340      * @return the native process id of the process
 341      * @throws UnsupportedOperationException if the Process implementation
 342      *         does not support this operation
 343      * @since 9
 344      */
 345     public long getPid() {
 346         return toHandle().getPid();
 347     }
 348 
 349     /**
 350      * Returns a {@code CompletableFuture<Process>} for the termination of the Process.
 351      * The {@link java.util.concurrent.CompletableFuture} provides the ability
 352      * to trigger dependent functions or actions that may be run synchronously
 353      * or asynchronously upon process termination.
 354      * When the process has terminated the CompletableFuture is
 355      * {@link java.util.concurrent.CompletableFuture#complete completed} regardless
 356      * of the exit status of the process.
 357      * <p>
 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
 360      * {@link java.util.concurrent.CompletableFuture#isDone done} or to
 361      * {@link java.util.concurrent.CompletableFuture#get() wait} for it to terminate.
 362      * {@link java.util.concurrent.CompletableFuture#cancel(boolean) Cancelling}
 363      * the CompletableFuture does not affect the Process.


 392      * {@link java.util.concurrent.CompletableFuture#complete completed} regardless
 393      * of the exit status of the process.
 394      *
 395      * This implementation may consume a lot of memory for thread stacks if a
 396      * large number of processes are waited for concurrently.
 397      * <p>
 398      * External implementations should override this method and provide
 399      * a more efficient implementation. For example, to delegate to the underlying
 400      * process, it can do the following:
 401      * <pre>{@code
 402      *    public CompletableFuture<Process> onExit() {
 403      *       return delegate.onExit().thenApply(p -> this);
 404      *    }
 405      * }</pre>
 406      * @apiNote
 407      * The process may be observed to have terminated with {@link #isAlive}
 408      * before the ComputableFuture is completed and dependent actions are invoked.
 409      *
 410      * @return a new {@code CompletableFuture<Process>} for the Process
 411      *
 412      * @since 9
 413      */
 414     public CompletableFuture<Process> onExit() {
 415         return CompletableFuture.supplyAsync(this::waitForInternal);
 416     }
 417 
 418     /**
 419      * Wait for the process to exit by calling {@code waitFor}.
 420      * If the thread is interrupted, remember the interrupted state to
 421      * be restored before returning. Use ForkJoinPool.ManagedBlocker
 422      * so that the number of workers in case ForkJoinPool is used is
 423      * compensated when the thread blocks in waitFor().
 424      *
 425      * @return the Process
 426      */
 427     private Process waitForInternal() {
 428         boolean interrupted = false;
 429         while (true) {
 430             try {
 431                 ForkJoinPool.managedBlock(new ForkJoinPool.ManagedBlocker() {
 432                     @Override


 454     /**
 455      * Returns a ProcessHandle for the Process.
 456      *
 457      * {@code Process} objects returned by {@link ProcessBuilder#start} and
 458      * {@link Runtime#exec} implement {@code toHandle} as the equivalent of
 459      * {@link ProcessHandle#of(long) ProcessHandle.of(pid)} including the
 460      * check for a SecurityManager and {@code RuntimePermission("manageProcess")}.
 461      *
 462      * @implSpec
 463      * This implementation throws an instance of
 464      * {@link java.lang.UnsupportedOperationException} and performs no other action.
 465      * Subclasses should override this method to provide a ProcessHandle for the
 466      * process.  The methods {@link #getPid}, {@link #info}, {@link #children},
 467      * and {@link #descendants}, unless overridden, operate on the ProcessHandle.
 468      *
 469      * @return Returns a ProcessHandle for the Process
 470      * @throws UnsupportedOperationException if the Process implementation
 471      *         does not support this operation
 472      * @throws SecurityException if a security manager has been installed and
 473      *         it denies RuntimePermission("manageProcess")
 474      * @since 9
 475      */
 476     public ProcessHandle toHandle() {
 477         throw new UnsupportedOperationException(this.getClass()
 478                 + ".toHandle() not supported");
 479     }
 480 
 481     /**
 482      * Returns a snapshot of information about the process.
 483      *
 484      * <p> A {@link ProcessHandle.Info} instance has accessor methods
 485      * that return information about the process if it is available.
 486      *
 487      * @implSpec
 488      * This implementation returns information about the process as:
 489      * {@link #toHandle toHandle().info()}.
 490      *
 491      * @return a snapshot of information about the process, always non-null
 492      * @throws UnsupportedOperationException if the Process implementation
 493      *         does not support this operation
 494      * @since 9
 495      */
 496     public ProcessHandle.Info info() {
 497         return toHandle().info();
 498     }
 499 
 500     /**
 501      * Returns a snapshot of the direct children of the process.
 502      * The parent of a direct child process is the process.
 503      * Typically, a process that is {@link #isAlive not alive} has no children.
 504      * <p>
 505      * <em>Note that processes are created and terminate asynchronously.
 506      * There is no guarantee that a process is {@link #isAlive alive}.
 507      * </em>
 508      *
 509      * @implSpec
 510      * This implementation returns the direct children as:
 511      * {@link #toHandle toHandle().children()}.
 512      *
 513      * @return a sequential Stream of ProcessHandles for processes that are
 514      *         direct children of the process
 515      * @throws UnsupportedOperationException if the Process implementation
 516      *         does not support this operation
 517      * @throws SecurityException if a security manager has been installed and
 518      *         it denies RuntimePermission("manageProcess")
 519      * @since 9
 520      */
 521     public Stream<ProcessHandle> children() {
 522         return toHandle().children();
 523     }
 524 
 525     /**
 526      * Returns a snapshot of the descendants of the process.
 527      * The descendants of a process are the children of the process
 528      * plus the descendants of those children, recursively.
 529      * Typically, a process that is {@link #isAlive not alive} has no children.
 530      * <p>
 531      * <em>Note that processes are created and terminate asynchronously.
 532      * There is no guarantee that a process is {@link #isAlive alive}.
 533      * </em>
 534      *
 535      * @implSpec
 536      * This implementation returns all children as:
 537      * {@link #toHandle toHandle().descendants()}.
 538      *
 539      * @return a sequential Stream of ProcessHandles for processes that
 540      *         are descendants of the process
 541      * @throws UnsupportedOperationException if the Process implementation
 542      *         does not support this operation
 543      * @throws SecurityException if a security manager has been installed and
 544      *         it denies RuntimePermission("manageProcess")
 545      * @since 9
 546      */
 547     public Stream<ProcessHandle> descendants() {
 548         return toHandle().descendants();
 549     }
 550 
 551 
 552 }
< prev index next >