Hi, The next step for JEP 102, Process API Updates is to provide an API to enumerate the hierarchy of processes and to be able to terminate a process tree. This draft javadoc <http://bussund0416/%7Erriggs/pdoc/>update [1] includes: - ProcessHandle class to provide handles to processes, their children, parent, process id and liveness - Process extends ProcessHandle and inherits the new behaviors - Method destroyProcessTree() terminates a process tree Additional functions related to termination and information about processes will be added in a later update. Comments appreciated, Roger [1] http://cr.openjdk.java.net/~rriggs/ph-apidraft/
On 06/25/2014 04:52 PM, roger riggs wrote:
Hi,
The next step for JEP 102, Process API Updates is to provide an API to enumerate the hierarchy of processes and to be able to terminate a process tree.
This draft javadoc <http://bussund0416/%7Erriggs/pdoc/>update [1] includes: - ProcessHandle class to provide handles to processes, their children, parent, process id and liveness - Process extends ProcessHandle and inherits the new behaviors - Method destroyProcessTree() terminates a process tree
Additional functions related to termination and information about processes will be added in a later update.
Comments appreciated, Roger
I still have a not-great feeling about the lack of atomicity inherent in these operations. At least when you're dealing with direct child processes (on UNIX-likes), there is some measure of control, in that a process is zombified until reaped by wait() and friends. Also I have a much higher level of concern about destroyProcessTree(), which I don't think has any place in this API. Control of any process belongs solely with their parent (or PID 1), in my opinion. Those concerns aside, what about making the allChildren() and allProcesses() methods lazy in some way? -- - DML
On 06/26/2014 12:05 AM, David M. Lloyd wrote:
On 06/25/2014 04:52 PM, roger riggs wrote:
Hi,
The next step for JEP 102, Process API Updates is to provide an API to enumerate the hierarchy of processes and to be able to terminate a process tree.
This draft javadoc <http://bussund0416/%7Erriggs/pdoc/>update [1] includes: - ProcessHandle class to provide handles to processes, their children, parent, process id and liveness - Process extends ProcessHandle and inherits the new behaviors - Method destroyProcessTree() terminates a process tree
Additional functions related to termination and information about processes will be added in a later update.
Comments appreciated, Roger
I still have a not-great feeling about the lack of atomicity inherent in these operations. At least when you're dealing with direct child processes (on UNIX-likes), there is some measure of control, in that a process is zombified until reaped by wait() and friends.
Also I have a much higher level of concern about destroyProcessTree(), which I don't think has any place in this API. Control of any process belongs solely with their parent (or PID 1), in my opinion.
Those concerns aside, what about making the allChildren() and allProcesses() methods lazy in some way?
Hi Roger, David, - Will there be a guarantee that ProcessHandle objects returned from factory methods: |current()| <http://cr.openjdk.java.net/%7Erriggs/ph-apidraft/java/lang/ProcessHandle.html#current-->, |of(long)| <http://cr.openjdk.java.net/%7Erriggs/ph-apidraft/java/lang/ProcessHandle.html#of-long->, |children()| <http://cr.openjdk.java.net/%7Erriggs/ph-apidraft/java/lang/ProcessHandle.html#children-->, |allChildren()| <http://cr.openjdk.java.net/%7Erriggs/ph-apidraft/java/lang/ProcessHandle.html#allChildren-->, |getParent()| <http://cr.openjdk.java.net/%7Erriggs/ph-apidraft/java/lang/ProcessHandle.html#getParent--> and |allProcesses()| <http://cr.openjdk.java.net/%7Erriggs/ph-apidraft/java/lang/ProcessHandle.html#allProcesses--> representing those processes that were started by ProcessBuilder API are actually the same Process objects that were returned from the ProcessBuilder API? The Process object can be viewed as a proxy of an OS process so as long as we have a reference to it, we can obtain it's exit status even though it has already been waited for (reaped) and we can reliably terminate it, because Process object is tracking the state of OS process and only forwards the termination request if it knows the OS process is still alive or zombified and so minimizes the probability to kill wrong process that just reused the same pid. The following expression: ProcessHandle.current().children() would therefore return just canonicalized Process objects (unless some native code embedded in the JVM process started sub-processes too). If returning canonicalized Process objects from factory methods is not desirable (some part of the program could mess with Input/Output streams of Process-es it did not have access to before), then perhaps ProcessHandle representing a process created by ProcessBuilder API would just have an internal private reference to the Process object to which it would forward method invocations... - There is an inconsistency in the javadoc for ProcessHandle.destroyForcibly(): public abstractProcessHandle <http://cr.openjdk.java.net/%7Erriggs/ph-apidraft/java/lang/ProcessHandle.html> destroyForcibly() Kills the process. The process represented by this |ProcessHandle| object is forcibly terminated. If the process is not alive no action is taken. Note: The process may not terminate immediately. i.e. |isAlive()| may return true for a brief period after |destroyForcibly()| is called. This method may be chained to |waitFor()| if needed. ...the method has a co-variant return type and there's no waitFor() method on the ProcessHandle. Why not? If ProcessHandle is a (or delegates to) Process then it could use it's waitFor(), if it is just a "foreign" ProcessHandle it could be implemented as a poll-ing wait for the isAlive() to return false... - Will there not be any destroyGracefully() method (which would be a no-op on platforms not supporting graceful termination)? - Depending on the OS facilities used to obtain process information (/proc/<pid> ?) there might be some other attributes already available. The name of a process would be nice to have. Regards, Peter
Hi Peter, Thanks for the comments... On 6/26/2014 4:55 AM, Peter Levart wrote:
On 06/26/2014 12:05 AM, David M. Lloyd wrote:
On 06/25/2014 04:52 PM, roger riggs wrote:
Hi,
The next step for JEP 102, Process API Updates is to provide an API to enumerate the hierarchy of processes and to be able to terminate a process tree.
This draft javadoc <http://bussund0416/%7Erriggs/pdoc/>update [1] includes: - ProcessHandle class to provide handles to processes, their children, parent, process id and liveness - Process extends ProcessHandle and inherits the new behaviors - Method destroyProcessTree() terminates a process tree
Additional functions related to termination and information about processes will be added in a later update.
Comments appreciated, Roger
I still have a not-great feeling about the lack of atomicity inherent in these operations. At least when you're dealing with direct child processes (on UNIX-likes), there is some measure of control, in that a process is zombified until reaped by wait() and friends.
Also I have a much higher level of concern about destroyProcessTree(), which I don't think has any place in this API. Control of any process belongs solely with their parent (or PID 1), in my opinion.
Those concerns aside, what about making the allChildren() and allProcesses() methods lazy in some way?
Hi Roger, David,
- Will there be a guarantee that ProcessHandle objects returned from factory methods: |current()| <http://cr.openjdk.java.net/%7Erriggs/ph-apidraft/java/lang/ProcessHandle.html#current-->, |of(long)| <http://cr.openjdk.java.net/%7Erriggs/ph-apidraft/java/lang/ProcessHandle.html#of-long->, |children()| <http://cr.openjdk.java.net/%7Erriggs/ph-apidraft/java/lang/ProcessHandle.html#children-->, |allChildren()| <http://cr.openjdk.java.net/%7Erriggs/ph-apidraft/java/lang/ProcessHandle.html#allChildren-->, |getParent()| <http://cr.openjdk.java.net/%7Erriggs/ph-apidraft/java/lang/ProcessHandle.html#getParent--> and |allProcesses()| <http://cr.openjdk.java.net/%7Erriggs/ph-apidraft/java/lang/ProcessHandle.html#allProcesses--> representing those processes that were started by ProcessBuilder API are actually the same Process objects that were returned from the ProcessBuilder API? The Process object can be viewed as a proxy of an OS process so as long as we have a reference to it, we can obtain it's exit status even though it has already been waited for (reaped) and we can reliably terminate it, because Process object is tracking the state of OS process and only forwards the termination request if it knows the OS process is still alive or zombified and so minimizes the probability to kill wrong process that just reused the same pid. The initial design does not have them returning Process instances. Process instances are capabilities and their reference accessibility is currently controlled by the code that created the Process. If ProcessHandle gave out those Process instances it would break existing encapsulation.
The following expression: ProcessHandle.current().children() would therefore return just canonicalized Process objects (unless some native code embedded in the JVM process started sub-processes too).
If returning canonicalized Process objects from factory methods is not desirable (some part of the program could mess with Input/Output streams of Process-es it did not have access to before), then perhaps ProcessHandle representing a process created by ProcessBuilder API would just have an internal private reference to the Process object to which it would forward method invocations...
yes, that would break encapsulation; not desirable and potential security issue. And yes, the implementation can maintain the association and delegate the behavior. It does not/should not make any difference in practice. Regardless of whether the TERM or KILL signal is delivered by an external process or via the ProcessHandle API, the Process mechanics should be the same. An application using the Process should see the same behavior, cleanup and termination, in either case.
- There is an inconsistency in the javadoc for ProcessHandle.destroyForcibly():
public abstractProcessHandle <http://cr.openjdk.java.net/%7Erriggs/ph-apidraft/java/lang/ProcessHandle.html> destroyForcibly() Kills the process. The process represented by this |ProcessHandle| object is forcibly terminated. If the process is not alive no action is taken.
Note: The process may not terminate immediately. i.e. |isAlive()| may return true for a brief period after |destroyForcibly()| is called. This method may be chained to |waitFor()| if needed.
...the method has a co-variant return type and there's no waitFor() method on the ProcessHandle. Why not? If ProcessHandle is a (or delegates to) Process then it could use it's waitFor(), if it is just a "foreign" ProcessHandle it could be implemented as a poll-ing wait for the isAlive() to return false...
I plan to address waitFor of ProcessHandle a bit later due to the complexities previously discussed for non-Process processes and when I can spend more time on the implementations and alternatives. Also requested are either Future style returns or lambda enabled onExit behavior.
- Will there not be any destroyGracefully() method (which would be a no-op on platforms not supporting graceful termination)?
An alternative is to add a method to report whether destroy is graceful or not. Either way an application needs to be aware of whether it worked or not so it can take some alternate action.
- Depending on the OS facilities used to obtain process information (/proc/<pid> ?) there might be some other attributes already available. The name of a process would be nice to have.
yep, also on the list and it builds naturally on top of ProcessHandle when the relationship between ProcessHandle and Process is settled. Thanks, Roger
Regards, Peter
On 6/26/14 7:23 AM, roger riggs wrote:
On 6/26/2014 4:55 AM, Peter Levart wrote:
- Will there be a guarantee that ProcessHandle objects returned from factory methods: [...] representing those processes that were started by ProcessBuilder API are actually the same Process objects that were returned from the ProcessBuilder API?
The initial design does not have them returning Process instances. Process instances are capabilities and their reference accessibility is currently controlled by the code that created the Process. If ProcessHandle gave out those Process instances it would break existing encapsulation.
Hi Roger, This is an interesting point about the undesirability of leaking Process instances. I initially thought the relationship between ProcessHandle and Process objects would be unspecified, and possibly left to the implementation. But based on your comments, it sounds like the PH factories are **prohibited** from returning any instances of Process. Thus we'd have: Process proc = new ProcessBuilder(...).start(); ProcessHandle ph = ProcessHandle.of(proc.getPid()); assert !(ph instanceof Process); It seems like it would be good idea to add this restriction to the specification. s'marks
Hi David, On 6/25/2014 6:05 PM, David M. Lloyd wrote:
On 06/25/2014 04:52 PM, roger riggs wrote:
Hi,
The next step for JEP 102, Process API Updates is to provide an API to enumerate the hierarchy of processes and to be able to terminate a process tree.
This draft javadoc <http://bussund0416/%7Erriggs/pdoc/>update [1] includes: - ProcessHandle class to provide handles to processes, their children, parent, process id and liveness - Process extends ProcessHandle and inherits the new behaviors - Method destroyProcessTree() terminates a process tree
Additional functions related to termination and information about processes will be added in a later update.
Comments appreciated, Roger
I still have a not-great feeling about the lack of atomicity inherent in these operations. At least when you're dealing with direct child processes (on UNIX-likes), there is some measure of control, in that a process is zombified until reaped by wait() and friends. The forcible termination implementation sends a kill signal and relies on the OS to finish the job. Perhaps the semantics need to be clearer that the method does not ensure the process has been cleaned up. The isAlive can be used to verify.
Also I have a much higher level of concern about destroyProcessTree(), which I don't think has any place in this API. Control of any process belongs solely with their parent (or PID 1), in my opinion.
That is the preferable situation as raised in earlier threads. However, in practice, if the parent dies, it is not always the case that PID 1 reaps them and they hang around.
Those concerns aside, what about making the allChildren() and allProcesses() methods lazy in some way?
Either using the old Enumeration pattern or perhaps some kind of Queue that returned instances until it could not find any new unique processes. They might be an issue with termination if processes were being created faster than the application was processing them. A bit pathological case perhaps but the application would not be aware it was not keeping up and might never finish. The snapshot of processes from the OS is pretty clean in a single native call. With the snapshot approach the application could re-do the snapshot and know there were new processes. Thanks, Roger
I have a question on the way this is modeled. By introducing a superclass, Process becomes a type of ProcessHandle. That doesn't seem right to me. I expect a Process to have a handle (not be one). Also I think these operations may make more sense as an interface. Cheers, Paul On Wed, Jun 25, 2014 at 4:52 PM, roger riggs <roger.riggs@oracle.com> wrote:
Hi,
The next step for JEP 102, Process API Updates is to provide an API to enumerate the hierarchy of processes and to be able to terminate a process tree.
This draft javadoc <http://bussund0416/%7Erriggs/pdoc/>update [1] includes: - ProcessHandle class to provide handles to processes, their children, parent, process id and liveness - Process extends ProcessHandle and inherits the new behaviors - Method destroyProcessTree() terminates a process tree
Additional functions related to termination and information about processes will be added in a later update.
Comments appreciated, Roger
Hi Paul, Whether an interface or class, it is desirable that Process have the new capabilities of iterating over children and destroying the tree and other possible additions retrieving information about the process like the process name, start time, etc. If Process had a ProcessHandle then the operations would less usable such as p.getProcessHandle().allChildren() or similar. From a security point of view, it is useful to know that ProcessHandle is concrete and not some arbitrary object hiding behind the interface. Roger On 6/26/2014 9:43 AM, Paul Benedict wrote:
I have a question on the way this is modeled. By introducing a superclass, Process becomes a type of ProcessHandle. That doesn't seem right to me. I expect a Process to have a handle (not be one). Also I think these operations may make more sense as an interface.
Cheers, Paul
On Wed, Jun 25, 2014 at 4:52 PM, roger riggs <roger.riggs@oracle.com <mailto:roger.riggs@oracle.com>> wrote:
Hi,
The next step for JEP 102, Process API Updates is to provide an API to enumerate the hierarchy of processes and to be able to terminate a process tree.
This draft javadoc <http://bussund0416/%7Erriggs/pdoc/>update [1] includes: - ProcessHandle class to provide handles to processes, their children, parent, process id and liveness - Process extends ProcessHandle and inherits the new behaviors - Method destroyProcessTree() terminates a process tree
Additional functions related to termination and information about processes will be added in a later update.
Comments appreciated, Roger
[1] http://cr.openjdk.java.net/~rriggs/ph-apidraft/ <http://cr.openjdk.java.net/%7Erriggs/ph-apidraft/>
participants (5)
-
David M. Lloyd
-
Paul Benedict
-
Peter Levart
-
roger riggs
-
Stuart Marks