views:

287

answers:

4

I'm creating subprocesses in this way:

String command = new String("some_program");

Process p = Runtime.getRuntime().exec(command);

How I can get that subprocess id?

P.S. I'm working on Linux.

+1  A: 

I tried (and failed) to do this a while back. I ended up wrapping my command in a shell script that dumped the pid to a file. Not the best solution but it got me past this hurdle.

Strawberry
This was the 1st idea, what I thought. But it doesn't fits to me. The "command" could be almost any program, not prepared by my. Thx anyway.
Pawka
+1  A: 

Well there is no documented way to do this, but it happens that the Process implementation class is UNIXProcess, and it has a pid field. So you could use reflection to access this private field to get the ID. Googling around you will find other tricks of calling another shell to get ps output and that kind of thing. Nothing easy.

Francis Upton
+11  A: 

There is still no public API for this (see http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4244896) but there are workarounds.

A first workaround would be to use an external program like ps and to call it using Runtime.exec() to get the pid :)

Another one is based on the fact that the java.lang.Process class is abstract and that you actually get a concrete subclass depending on your platform. On Linux, you'll get a java.lang.UnixProcess which has a private field int pid. Using reflection, you can easily get the value of this field:

Field f = p.getClass().getDeclaredField("pid");
f.setAccessible(true);
System.out.println( f.get( p ) );
Pascal Thivent
nice.. I wonder why this isn't public?
Bozho
Good question! And I wonder why such a bug is open for 10+ years without resolution?
Pascal Thivent
Probably because Sun want you to stay inside the JVM.
Thorbjørn Ravn Andersen
Maybe because the request is about java.lang.System. And putting PID there turns it into platform-specific, which is wrong. But UnixProcess has no reason for hiding it.
Bozho
Thanks, works perfectly. Just filled RFE @ sun.com to solve this problem.
Pawka
@Bozho Well, you shouldn't actually have to manipulate a platform specific class like `UnixProcess`.
Pascal Thivent
@Thorbjørn I guess you're right here.
Pascal Thivent
@Pawka - why don't you vote for the existing issue. And get all your friends to as well.
Stephen C
Well, you don't manipulate it, you just get its state. If it is not part of the API, they should put it in com.sun.*
Bozho
+1  A: 

From here

public static void main(String[] args) throws IOException {
    byte[] bo = new byte[100];
    String[] cmd = {"bash", "-c", "echo $PPID"};
    Process p = Runtime.getRuntime().exec(cmd);
    p.getInputStream().read(bo);
    System.out.println(new String(bo));
}
Bozho
I've found that post before, but it doesn't fits to me. I can't prepare of modify subprocess program that it would output PID.
Pawka