aspose file tools*
The moose likes Linux / UNIX and the fly likes Get the UNIX process ID of the java program Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Spring in Action this week in the Spring forum!
JavaRanch » Java Forums » Engineering » Linux / UNIX
Bookmark "Get the UNIX process ID of the java program" Watch "Get the UNIX process ID of the java program" New topic
Author

Get the UNIX process ID of the java program

Anonymous
Ranch Hand

Joined: Nov 22, 2008
Posts: 18944
Hi there,
I need to start a java program, and the program
will use its UNIX process ID to do some processing.
How can I find the UNIX PID inside the java program?
Thanks,
Mike.
George Brown
Ranch Hand

Joined: Sep 26, 2000
Posts: 919
That's an interesting problem.
But is it appropriate for a Java program to get the UNIX PID? You would be looking for the PID of the JVM, and since Java is meant to be OS-independent, if it is possible it would make your java code thoroughly non-portable. For that reason, I would imagine that Sun has made no provision for it in their Standard Edition.
My solution would be to rewrite the program in C or C++ and to use getpid().
Vlad Patryshev
Ranch Hand

Joined: Jun 30, 2001
Posts: 61
This is an interesting answer.
How then can I find a way to tell one runnin ginstance of the same java program from another, be it on Unix or on Windows or on Mac or on my cellphone?


Thanks,<br />Vlad
William Barnes
Ranch Hand

Joined: Mar 16, 2001
Posts: 986

I just wrote some code that did that. I was trying to make a unique ID with the pid of the JVM as one of the attributes. You need to write a small c/c++ program that does "getpid()" and than use JNI to call it.


Please ignore post, I have no idea what I am talking about.
Michael Schloh von Bennew
Greenhorn

Joined: Oct 11, 2001
Posts: 1
Originally posted by christopher foran:
I just wrote some code that did that. I was trying to make a unique ID with the pid of the JVM as one of the attributes. You need to write a small c/c++ program that does "getpid()" and than use JNI to call it.

Can you please post your code? Especially interesteing is how you called the c++ portion from within java (JNI?)
Michael Ernest
High Plains Drifter
Sheriff

Joined: Oct 25, 2000
Posts: 7292

The easiest way to get the PID is through the shell environment variable $$. Use a System.exec() call to "echo $$"
I don't agree that this is inappropriate for a Java program -- it just has the unhappy side effect of making the program non-portable across OS platforms. If you don't care about platform-agnostic code -- and I don't see how you can if you care about PIDs -- Java is still *way* easier to use than C.
------------------
Michael Ernest, co-author of: The Complete Java 2 Certification Study Guide
[This message has been edited by Michael Ernest (edited October 12, 2001).]


Make visible what, without you, might perhaps never have been seen.
- Robert Bresson
George Brown
Ranch Hand

Joined: Sep 26, 2000
Posts: 919
Originally posted by Michael Ernest:
The easiest way to get the PID is through the shell environment variable $$. Use a System.exec() call to "echo $$"

I guess you mean a Runtime.exec() call ?
I thought those were always run in a separate (spawned) process, and if you use "echo $$" you get the PID of that process rather than the running java process. On the other hand, if you're using the Korn shell (or equivalent) I guess you could use "echo $PPID" to get the PID of the shell's parent (ie. the java process).
But I still don't think that java is ideal for grabbing PIDs even though it can be easier than some other programming languages.
Michael Ernest
High Plains Drifter
Sheriff

Joined: Oct 25, 2000
Posts: 7292

oops -- good point on PPID.
Jim Lang
Greenhorn

Joined: Oct 04, 2000
Posts: 27
So I tried a practical example, and used the following lines:

However, that only gives me a way to output the input stream to the subprocess. How can I capture the output stream of the executed subprocess? Is this possible?
[This message has been edited by Jim Lang (edited October 13, 2001).]
Michael Ernest
High Plains Drifter
Sheriff

Joined: Oct 25, 2000
Posts: 7292

Process supports both getInputStream() and getOutputStream().
------------------
Michael Ernest, co-author of: The Complete Java 2 Certification Study Guide
Roseanne Zhang
Ranch Hand

Joined: Nov 14, 2000
Posts: 1953
Did any body tried, I admit that I tried and could not make it work. The output is $PPID instead of the number. If any of you made it work, please tell me how. Thanks a lot!!!
If I directly call "echo $$" or "echo $PPID" or "sh -c 'echo $PPID'" from prompt, they all works, but put them in the code, none works.
Here is my modified code from above
Roseanne Zhang
Ranch Hand

Joined: Nov 14, 2000
Posts: 1953
It compiles, runs, and has output, but no process IDs.
Help!
Michael Ernest
High Plains Drifter
Sheriff

Joined: Oct 25, 2000
Posts: 7292

Ok, figured it out. I thought of this problem before but got lazy and didn't test. Actually, I didn't write anything to test. But hey, just another example of free help achieving its true worth.
Runtime.exec() generates a Unix system call execve(), which you can see by trussing the JVM process. On Solaris I did this with
$ truss -af java CC 2>errorlog
That way all the process results go to the console while the truss output goes to errorlog (and there's a mess o' truss output).

I naively assumed that Runtime.exec() would spawn a shell, which it does not. You need a shell to get environment variables like $PPID. So I wrote a script called rtn and invoked that from Runtime.exec(). Here's Roseanne's code slightly modified:

and here is the script rtn:

This does the trick. Make sure the execute bits are on for the file rtn.
------------------
Michael Ernest, co-author of: The Complete Java 2 Certification Study Guide
[This message has been edited by Michael Ernest (edited October 18, 2001).]
Roseanne Zhang
Ranch Hand

Joined: Nov 14, 2000
Posts: 1953
Michael
Thank you so much for the help!!!
I still did not get it to work.
The code above is not compilable, 3 compile errors. After I fixed them, I got either a shell error message or runtime exception, it depends I put "rtn" or ". rtn" as my command.
If I directly run the shell script by ". rtn", it works fine.
I'll look into it more. If you have some idea what mistake i've made, please let me know. Thanks again.
What a busy day!!!
Roseanne
George Brown
Ranch Hand

Joined: Sep 26, 2000
Posts: 919
Roseanne,
Michael's code definitely works (with the minor fixes - I think he was in a hurry).
Nice one Michael, but I'd venture that it still feels a bit Heath Robinson to me when you could use getpid(), getppid(), etc. C isn't that tricky, especially when the system calls are all laid out for you...
Just my opinion perhaps.
[This message has been edited by George Brown (edited October 19, 2001).]
Michael Ernest
High Plains Drifter
Sheriff

Joined: Oct 25, 2000
Posts: 7292

Hey George
I don't know the Heath Robinson reference but I get what you're saying. I can think of a few related tradeoffs:
- What Ive demonstrated is skeletal, I presume what the original enquirer wants to do is far more involved, and possibly wants to keep overhead to a minimum; and
- $PPID is known by the shell, so you don't need to make a system call. The cost of a system call is negligible in this example, of course, but if you were looking to save the trap into kernel execution, this would do it. But even if you're trying to dash something off;
- You don't need a compiler handy to do it this way. Living off Solaris and often changing machines as I do, that's meaningful to me. YMMV.
------------------
Michael Ernest, co-author of: The Complete Java 2 Certification Study Guide
George Brown
Ranch Hand

Joined: Sep 26, 2000
Posts: 919
Originally posted by Michael Ernest:
I don't know the Heath Robinson reference but I get what you're saying.

This url should make my comment clearer (a real gem of a cartoonist)... http://www.bbc.co.uk/history/discovery/bypeople/robinson_01.shtml
Janardhan Babu Chinta
Greenhorn

Joined: Nov 08, 2001
Posts: 1
import java.io.*;
public class CC{
public CC(){
BufferedReader stdout;
Process process;
try {
process = Runtime.getRuntime().exec("ppid");
stdout = new BufferedReader(new InputStreamReader(process.getInputStream()));
int exitVal = process.waitFor();
String line;
while ((line=stdout.readLine())!= null) System.out.println(line);
// uncomment the below line and make the java process not die
// the pid of java vm is printed on the console
// u can check pid using the 'ps -ef | grep CC' command
// while(true) Thread.currentThread().sleep(1000);
}catch(Exception ex){
ex.printStackTrace();
}
}
public static void main(String args[]) {
CC run = new CC();
}
}

// to compile use
// gcc -o ppid ppid.c
int main(){
printf("%d\n",getppid());
return 0;
}
Marcond Marchi
Greenhorn

Joined: Oct 01, 2005
Posts: 1
Hi there. If You don't have access to a C compiler, the shell macros can be used to get the pid:

static int getPid ()
{
Random r = new Random ();

// Let's create a hand-made pid for default
int pid = r.nextInt () & 0x7fffffff;

// Cmd to obtain the pid using macro ($PPID becomes the pid number)
String cmd = "/bin/sh -c @$PPID@";

try
{
Process myProcess = Runtime.getRuntime ().exec (cmd);
// Yes, the cmd above hopefully leads to an error msg - with the pid number we need
InputStream is = myProcess.getErrorStream();
BufferedReader stdout = new BufferedReader(new InputStreamReader(is));

String line = stdout.readLine();

StringTokenizer st = new StringTokenizer (line, "@");

if (st.hasMoreTokens ())
{
st.nextToken ();

int ppid = Integer.parseInt (st.nextToken ());

if (ppid > 0)
{
pid = ppid;

System.out.println ("JVM real Pid: " + pid);
}
}
}
catch (Exception e)
{
// Problem obtaining pid, lets keep the hand-made pid.
System.out.println ("JVM hand-made Pid: " + pid);
}

return (pid);
}

It's just a clue, because I have tested this method of getting the PPID and it looks to me that before spawnning the exec (on Linux) the Java forks a new Java process, that is the parent pid, that dies when the spawned command terminates. The result is that multiple calls to getPid() returns increasing numbers. I haven't tested this somewhere else (Solaris, AIX), so Your milleage may vary.
Stefan Wagner
Ranch Hand

Joined: Jun 02, 2003
Posts: 1923

Let's hope, Mike L. was patient enough the last 5 years, to wait for this solution.

btw.: can you edit your post and decorate the code by using code-tags, to make indentation work properly?


http://home.arcor.de/hirnstrom/bewerbung
Kaido Lepisto
Greenhorn

Joined: Mar 30, 2007
Posts: 1
FWIW, here's my humble solution to the same problem. I needed the PID too , so I did some poking and discovered the script is unnecessary and it also works with bash.

Mr. C Lamont Gilbert
Ranch Hand

Joined: Oct 05, 2001
Posts: 1170

You can create a small shell script to start your java program and record the PID into a text file. Some linux programs do this so they are able to shut themselves down with a similar script call.
Raghavan Muthu
Ranch Hand

Joined: Apr 20, 2006
Posts: 3344

Scott Arrowood wrote:Joe, While I agree about waking zombies, All seven years of info is beneficial to those of us who happen to be looking for it the first time. Thanks for the help guys.


Yes of course. I just remember the recent discussion on the same topic yesterday with Paul Wheaton here.

My Google search took me here and it was good to get/see the updated/added information upon the older replies! (whether the link *really* helps the individual or not to solve his issue).

As Eric mentioned in the linked URL, the second point ("People saying I have a similar problem [Start a new thread, do not hijack, add a link back]") still holds good. Right?

Of course, the opinion differs!

Everything has got its own deadline including one's EGO!
[CodeBarn] [Java Concepts-easily] [Corey's articles] [SCJP-SUN] [Servlet Examples] [Java Beginners FAQ] [Sun-Java Tutorials] [Java Coding Guidelines]
Steve Eriksson
Greenhorn

Joined: Aug 23, 2011
Posts: 1
This method can extract the UNIX PID from the Process. It might not work on every platform and implementation but it seems to work fine on GNU/Linux and Oracle JRE 1.6.

Emilia con
Greenhorn

Joined: Oct 28, 2011
Posts: 3
If I get a process object in Java through Runtime.getRuntime().exec(...), or ProcessBuilder.start(), I can wait for it through Process.waitFor(), which is like Thread.join(), or I could kill it with Process.destroy(), which is like the deprecated Thread.stop(). BUT: How do I find the pid of the Process Object? I don't see a method for doing that in The Official Documentation. Can I do this in Java? If so, how?
Duc Quoc
Greenhorn

Joined: Dec 15, 2011
Posts: 4

Emilia con wrote:If I get a process object in Java through Runtime.getRuntime().exec(...), or ProcessBuilder.start(), I can wait for it through Process.waitFor(), which is like Thread.join(), or I could kill it with Process.destroy(), which is like the deprecated Thread.stop(). BUT: How do I find the pid of the Process Object? I don't see a method for doing that in The Official Documentation. Can I do this in Java? If so, how?

Did you try the above suggestions?

I would try to invoke the "jps" (assumed Sun's JDK) with the Runtime.exec(...) , if I were you

--Duc

Duc's blog: http://ducquoc.wordpress.com
Ken Tanaka
Greenhorn

Joined: Jan 06, 2014
Posts: 1
For Groovy and Java 1.6:

Taken from http://snipplr.com/view/20787/
The name should be something like "12345@host.example.com" (This is not guaranteed, and can vary by Java implementation)

Alternatively, if you are using Groovy on a linux/unix platform, here is how the PID can be retreived from a shell execution:
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 39396
    
  28
welcome to the Ranch
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Get the UNIX process ID of the java program