2015-05-29 14:04:12 -04:00
|
|
|
/*
|
|
|
|
* Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
|
|
|
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
|
|
*
|
|
|
|
* This code is free software; you can redistribute it and/or modify it
|
|
|
|
* under the terms of the GNU General Public License version 2 only, as
|
|
|
|
* published by the Free Software Foundation. Oracle designates this
|
|
|
|
* particular file as subject to the "Classpath" exception as provided
|
|
|
|
* by Oracle in the LICENSE file that accompanied this code.
|
|
|
|
*
|
|
|
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
|
|
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
|
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
|
|
* version 2 for more details (a copy is included in the LICENSE file that
|
|
|
|
* accompanied this code).
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License version
|
|
|
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
|
|
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
|
|
*
|
|
|
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
|
|
|
* or visit www.oracle.com if you need additional information or have any
|
|
|
|
* questions.
|
|
|
|
*/
|
|
|
|
package java.lang;
|
|
|
|
|
|
|
|
import java.time.Duration;
|
|
|
|
import java.time.Instant;
|
|
|
|
import java.util.Optional;
|
|
|
|
import java.util.concurrent.CompletableFuture;
|
|
|
|
import java.util.stream.Stream;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* ProcessHandle identifies and provides control of native processes. Each
|
|
|
|
* individual process can be monitored for liveness, list its children,
|
|
|
|
* get information about the process or destroy it.
|
|
|
|
* By comparison, {@link java.lang.Process Process} instances were started
|
|
|
|
* by the current process and additionally provide access to the process
|
|
|
|
* input, output, and error streams.
|
|
|
|
* <p>
|
|
|
|
* The native process ID is an identification number that the
|
|
|
|
* operating system assigns to the process.
|
|
|
|
* The range for process id values is dependent on the operating system.
|
|
|
|
* For example, an embedded system might use a 16-bit value.
|
|
|
|
* Status information about a process is retrieved from the native system
|
|
|
|
* and may change asynchronously; processes may be created or terminate
|
|
|
|
* spontaneously.
|
|
|
|
* The time between when a process terminates and the process id
|
|
|
|
* is reused for a new process is unpredictable.
|
|
|
|
* Race conditions can exist between checking the status of a process and
|
|
|
|
* acting upon it. When using ProcessHandles avoid assumptions
|
|
|
|
* about the liveness or identity of the underlying process.
|
|
|
|
* <p>
|
|
|
|
* Each ProcessHandle identifies and allows control of a process in the native
|
|
|
|
* system. ProcessHandles are returned from the factory methods {@link #current()},
|
|
|
|
* {@link #of(long)},
|
|
|
|
* {@link #children}, {@link #allChildren}, {@link #parent()} and
|
|
|
|
* {@link #allProcesses()}.
|
|
|
|
* <p>
|
|
|
|
* The {@link Process} instances created by {@link ProcessBuilder} can be queried
|
|
|
|
* for a ProcessHandle that provides information about the Process.
|
|
|
|
* ProcessHandle references should not be freely distributed.
|
|
|
|
*
|
|
|
|
* <p>
|
|
|
|
* A {@link java.util.concurrent.CompletableFuture} available from {@link #onExit}
|
|
|
|
* can be used to wait for process termination, and possibly trigger dependent
|
|
|
|
* actions.
|
|
|
|
* <p>
|
|
|
|
* The factory methods limit access to ProcessHandles using the
|
|
|
|
* SecurityManager checking the {@link RuntimePermission RuntimePermission("manageProcess")}.
|
|
|
|
* The ability to control processes is also restricted by the native system,
|
|
|
|
* ProcessHandle provides no more access to, or control over, the native process
|
|
|
|
* than would be allowed by a native application.
|
2015-06-08 16:37:53 +04:00
|
|
|
*
|
2015-05-29 14:04:12 -04:00
|
|
|
* @implSpec
|
|
|
|
* In the case where ProcessHandles cannot be supported then the factory
|
|
|
|
* methods must consistently throw {@link java.lang.UnsupportedOperationException}.
|
|
|
|
* The methods of this class throw {@link java.lang.UnsupportedOperationException}
|
|
|
|
* if the operating system does not allow access to query or kill a process.
|
|
|
|
*
|
|
|
|
* @see Process
|
|
|
|
* @since 1.9
|
|
|
|
*/
|
|
|
|
public interface ProcessHandle extends Comparable<ProcessHandle> {
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns the native process ID of the process. The native process ID is an
|
|
|
|
* identification number that the operating system assigns to the process.
|
|
|
|
*
|
|
|
|
* @return the native process ID of the process
|
|
|
|
* @throws UnsupportedOperationException if the implementation
|
|
|
|
* does not support this operation
|
|
|
|
*/
|
|
|
|
long getPid();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns an {@code Optional<ProcessHandle>} for an existing native process.
|
|
|
|
*
|
|
|
|
* @param pid a native process ID
|
|
|
|
* @return an {@code Optional<ProcessHandle>} of the PID for the process;
|
|
|
|
* the {@code Optional} is empty if the process does not exist
|
|
|
|
* @throws SecurityException if a security manager has been installed and
|
|
|
|
* it denies RuntimePermission("manageProcess")
|
|
|
|
* @throws UnsupportedOperationException if the implementation
|
|
|
|
* does not support this operation
|
|
|
|
*/
|
|
|
|
public static Optional<ProcessHandle> of(long pid) {
|
|
|
|
return ProcessHandleImpl.get(pid);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns a ProcessHandle for the current process. The ProcessHandle cannot be
|
|
|
|
* used to destroy the current process, use {@link System#exit System.exit} instead.
|
|
|
|
*
|
|
|
|
* @return a ProcessHandle for the current process
|
|
|
|
* @throws SecurityException if a security manager has been installed and
|
|
|
|
* it denies RuntimePermission("manageProcess")
|
|
|
|
* @throws UnsupportedOperationException if the implementation
|
|
|
|
* does not support this operation
|
|
|
|
*/
|
|
|
|
public static ProcessHandle current() {
|
|
|
|
return ProcessHandleImpl.current();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns an {@code Optional<ProcessHandle>} for the parent process.
|
|
|
|
* Note that Processes in a zombie state usually don't have a parent.
|
|
|
|
*
|
|
|
|
* @return an {@code Optional<ProcessHandle>} of the parent process;
|
|
|
|
* the {@code Optional} is empty if the child process does not have a parent
|
|
|
|
* or if the parent is not available, possibly due to operating system limitations
|
|
|
|
* @throws SecurityException if a security manager has been installed and
|
|
|
|
* it denies RuntimePermission("manageProcess")
|
|
|
|
*/
|
|
|
|
Optional<ProcessHandle> parent();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns a snapshot of the current direct children of the process.
|
|
|
|
* A process that is {@link #isAlive not alive} has zero children.
|
|
|
|
* <p>
|
|
|
|
* <em>Note that processes are created and terminate asynchronously.
|
|
|
|
* There is no guarantee that a process is {@link #isAlive alive}.
|
|
|
|
* </em>
|
|
|
|
*
|
|
|
|
* @return a Stream of ProcessHandles for processes that are direct children
|
|
|
|
* of the process
|
|
|
|
* @throws SecurityException if a security manager has been installed and
|
|
|
|
* it denies RuntimePermission("manageProcess")
|
|
|
|
*/
|
|
|
|
Stream<ProcessHandle> children();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns a snapshot of the current direct and indirect children of the process.
|
|
|
|
* A process that is {@link #isAlive not alive} has zero children.
|
|
|
|
* <p>
|
|
|
|
* <em>Note that processes are created and terminate asynchronously.
|
|
|
|
* There is no guarantee that a process is {@link #isAlive alive}.
|
|
|
|
* </em>
|
|
|
|
*
|
|
|
|
* @return a Stream of ProcessHandles for processes that are direct and
|
|
|
|
* indirect children of the process
|
|
|
|
* @throws SecurityException if a security manager has been installed and
|
|
|
|
* it denies RuntimePermission("manageProcess")
|
|
|
|
*/
|
|
|
|
Stream<ProcessHandle> allChildren();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns a snapshot of all processes visible to the current process.
|
|
|
|
* <p>
|
|
|
|
* <em>Note that processes are created and terminate asynchronously. There
|
|
|
|
* is no guarantee that a process in the stream is alive or that no other
|
|
|
|
* processes may have been created since the inception of the snapshot.
|
|
|
|
* </em>
|
|
|
|
*
|
|
|
|
* @return a Stream of ProcessHandles for all processes
|
|
|
|
* @throws SecurityException if a security manager has been installed and
|
|
|
|
* it denies RuntimePermission("manageProcess")
|
|
|
|
* @throws UnsupportedOperationException if the implementation
|
|
|
|
* does not support this operation
|
|
|
|
*/
|
|
|
|
static Stream<ProcessHandle> allProcesses() {
|
|
|
|
return ProcessHandleImpl.children(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns a snapshot of information about the process.
|
|
|
|
*
|
|
|
|
* <p> An {@code Info} instance has various accessor methods that return
|
|
|
|
* information about the process, if the process is alive and the
|
|
|
|
* information is available.
|
|
|
|
*
|
|
|
|
* @return a snapshot of information about the process, always non-null
|
|
|
|
*/
|
|
|
|
Info info();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Information snapshot about the process.
|
|
|
|
* The attributes of a process vary by operating system and are not available
|
|
|
|
* in all implementations. Information about processes is limited
|
|
|
|
* by the operating system privileges of the process making the request.
|
|
|
|
* The return types are {@code Optional<T>} allowing explicit tests
|
|
|
|
* and actions if the value is available.
|
|
|
|
* @since 1.9
|
|
|
|
*/
|
|
|
|
public interface Info {
|
|
|
|
/**
|
|
|
|
* Returns the executable pathname of the process.
|
|
|
|
*
|
|
|
|
* @return an {@code Optional<String>} of the executable pathname
|
|
|
|
* of the process
|
|
|
|
*/
|
|
|
|
public Optional<String> command();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns an array of Strings of the arguments of the process.
|
|
|
|
*
|
|
|
|
* @return an {@code Optional<String[]>} of the arguments of the process
|
|
|
|
*/
|
|
|
|
public Optional<String[]> arguments();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns the start time of the process.
|
|
|
|
*
|
|
|
|
* @return an {@code Optional<Instant>} of the start time of the process
|
|
|
|
*/
|
|
|
|
public Optional<Instant> startInstant();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns the total cputime accumulated of the process.
|
|
|
|
*
|
|
|
|
* @return an {@code Optional<Duration>} for the accumulated total cputime
|
|
|
|
*/
|
|
|
|
public Optional<Duration> totalCpuDuration();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Return the user of the process.
|
|
|
|
*
|
|
|
|
* @return an {@code Optional<String>} for the user of the process
|
|
|
|
*/
|
|
|
|
public Optional<String> user();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns a {@code CompletableFuture<ProcessHandle>} for the termination
|
|
|
|
* of the process.
|
|
|
|
* The {@link 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 terminates the CompletableFuture is
|
|
|
|
* {@link java.util.concurrent.CompletableFuture#complete completed} regardless
|
|
|
|
* of the exit status of the process.
|
|
|
|
* The {@code onExit} method can be called multiple times to invoke
|
|
|
|
* independent actions when the process exits.
|
|
|
|
* <p>
|
|
|
|
* Calling {@code onExit().get()} waits for the process to terminate and returns
|
|
|
|
* the ProcessHandle. The future can be used to check if the process is
|
|
|
|
* {@link java.util.concurrent.CompletableFuture#isDone done} or to
|
|
|
|
* {@link java.util.concurrent.Future#get() wait} for it to terminate.
|
|
|
|
* {@link java.util.concurrent.Future#cancel(boolean) Cancelling}
|
|
|
|
* the CompleteableFuture does not affect the Process.
|
|
|
|
* <p>
|
|
|
|
* If the process is {@link #isAlive not alive} the {@link CompletableFuture}
|
|
|
|
* returned has been {@link java.util.concurrent.CompletableFuture#complete completed}.
|
|
|
|
*
|
|
|
|
* @return a new {@code CompletableFuture<ProcessHandle>} for the ProcessHandle
|
|
|
|
*
|
|
|
|
* @throws IllegalStateException if the process is the current process
|
|
|
|
*/
|
|
|
|
CompletableFuture<ProcessHandle> onExit();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns {@code true} if the implementation of {@link #destroy}
|
|
|
|
* normally terminates the process.
|
|
|
|
* Returns {@code false} if the implementation of {@code destroy}
|
|
|
|
* forcibly and immediately terminates the process.
|
|
|
|
*
|
|
|
|
* @return {@code true} if the implementation of {@link #destroy}
|
|
|
|
* normally terminates the process;
|
|
|
|
* otherwise, {@link #destroy} forcibly terminates the process
|
|
|
|
*/
|
|
|
|
boolean supportsNormalTermination();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Requests the process to be killed.
|
|
|
|
* Whether the process represented by this {@code ProcessHandle} object is
|
|
|
|
* {@link #supportsNormalTermination normally terminated} or not is
|
|
|
|
* implementation dependent.
|
|
|
|
* Forcible process destruction is defined as the immediate termination of the
|
|
|
|
* process, whereas normal termination allows the process to shut down cleanly.
|
|
|
|
* If the process is not alive, no action is taken.
|
|
|
|
* The operating system access controls may prevent the process
|
|
|
|
* from being killed.
|
|
|
|
* <p>
|
|
|
|
* The {@link java.util.concurrent.CompletableFuture} from {@link #onExit} is
|
|
|
|
* {@link java.util.concurrent.CompletableFuture#complete completed}
|
|
|
|
* when the process has terminated.
|
|
|
|
* <p>
|
|
|
|
* Note: The process may not terminate immediately.
|
|
|
|
* For example, {@code isAlive()} may return true for a brief period
|
|
|
|
* after {@code destroy()} is called.
|
|
|
|
*
|
|
|
|
* @return {@code true} if termination was successfully requested,
|
|
|
|
* otherwise {@code false}
|
|
|
|
* @throws IllegalStateException if the process is the current process
|
|
|
|
*/
|
|
|
|
boolean destroy();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Requests the process to be killed forcibly.
|
|
|
|
* The process represented by this {@code ProcessHandle} object is
|
|
|
|
* forcibly terminated.
|
|
|
|
* Forcible process destruction is defined as the immediate termination of the
|
|
|
|
* process, whereas normal termination allows the process to shut down cleanly.
|
|
|
|
* If the process is not alive, no action is taken.
|
|
|
|
* The operating system access controls may prevent the process
|
|
|
|
* from being killed.
|
|
|
|
* <p>
|
|
|
|
* The {@link java.util.concurrent.CompletableFuture} from {@link #onExit} is
|
|
|
|
* {@link java.util.concurrent.CompletableFuture#complete completed}
|
|
|
|
* when the process has terminated.
|
|
|
|
* <p>
|
|
|
|
* Note: The process may not terminate immediately.
|
|
|
|
* For example, {@code isAlive()} may return true for a brief period
|
|
|
|
* after {@code destroyForcibly()} is called.
|
|
|
|
*
|
|
|
|
* @return {@code true} if termination was successfully requested,
|
|
|
|
* otherwise {@code false}
|
|
|
|
* @throws IllegalStateException if the process is the current process
|
|
|
|
*/
|
|
|
|
boolean destroyForcibly();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Tests whether the process represented by this {@code ProcessHandle} is alive.
|
|
|
|
* Process termination is implementation and operating system specific.
|
|
|
|
* The process is considered alive as long as the PID is valid.
|
|
|
|
*
|
|
|
|
* @return {@code true} if the process represented by this
|
|
|
|
* {@code ProcessHandle} object has not yet terminated
|
|
|
|
*/
|
|
|
|
boolean isAlive();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Compares this ProcessHandle with the specified ProcessHandle for order.
|
|
|
|
* The order is not specified, but is consistent with {@link Object#equals},
|
|
|
|
* which returns {@code true} if and only if two instances of ProcessHandle
|
|
|
|
* are of the same implementation and represent the same system process.
|
|
|
|
* Comparison is only supported among objects of same implementation.
|
|
|
|
* If attempt is made to mutually compare two different implementations
|
|
|
|
* of {@link ProcessHandle}s, {@link ClassCastException} is thrown.
|
|
|
|
*
|
|
|
|
* @param other the ProcessHandle to be compared
|
|
|
|
* @return a negative integer, zero, or a positive integer as this object
|
|
|
|
* is less than, equal to, or greater than the specified object.
|
|
|
|
* @throws NullPointerException if the specified object is null
|
|
|
|
* @throws ClassCastException if the specified object is not of same class
|
|
|
|
* as this object
|
|
|
|
*/
|
|
|
|
@Override
|
|
|
|
int compareTo(ProcessHandle other);
|
|
|
|
|
|
|
|
}
|