[vox-tech] HOWTO: Get Process ID from inside Java?

vox-tech@lists.lugod.org vox-tech@lists.lugod.org
Thu, 23 Jan 2003 01:40:09 -0500


  I've been looking for info about getting the process id of a running java 
program from inside java.  Amazingly enough it appears that getpid and 
other similar of functions are not available to a native java program.
After browsing around for an hour I have found five common work arounds
for this language omission:

- Have a shell script pass into the java process it's own PID on the 
  command line: "exec java ClassName $$"

- Fork and exec another process from within the java which echos or 
  returns the Parent Process Id for the java process to catch and parse...
  (see method 2)

- Have a shell script which starts the java process save to a text file
  java process's pid, then have java read that file: 
  "java ClassName & echo $! > pid.txt"

- Use JNI to call a c stub to invoke the operating system's getpid 
  function (method 4);

- Use some form of "ps auxww | grep MagicString" to find the correct 
  process id and parse the ps line <bleh>.

... All of this is just getting too gross for words.  I'm wondering if any
Java guru's out there have found a simple hole in the Java (hide useful 
information from running code) mentality and know of a fairly clean way
to get the process id of the current running VM.

    Thanks,
      Mike


  In this particular case I would like the process id to use as part of
a log file name.  This is for a java server which is unstable and so 
multiple java process are run at the same time so when one starts getting 
borked it simply needs to be killed (a nanny program will restart dead
server processes so that the server appears to be stable).  ... 


method 2:
===
  try
  {
    Process p = Runtime.getRuntime().exec(
      new String[] {"perl", "-e", "print getppid(). \"\n\";"});

    BufferedReader br =
      new BufferedReader(new InputStreamReader(p.getInputStream()));

    int pid = Integer.parseInt(br.readLine());

    System.out.println(pid);

    p.destroy();
    p = null;
    br = null;
  }
  catch (java.io.IOException e)
  {
    System.out.println(e);
  }
===

method 4:
===
// Pid.java
class Pid {
  static { System.loadLibrary("Pid"); }
  public native int getPid();

  public static void main(String args[])
  {
          Pid z = new Pid();
          System.out.println(z.getPid());
          z = null;
  }
}

// Pid.c
#include "Pid.h"
#include "unistd.h"
JNIEXPORT jint JNICALL Java_Pid_getPid(JNIEnv *env, jobject obj)
{ return getpid(); }
===

javac Pid.java
javah Pid
gcc -I/usr/lib/j2se/1.3/include -I/usr/lib/j2se/1.3/include/linux --shared -o libPid.so Pid.c

export LD_LIBRARY_PATH=`pwd`
ls -l libPid.so 
-rwxr-xr-x    1 msimons  msimons      5111 Jan 22 22:23 libPid.so

  This method requires a c stub be compiled for each platform to be 
supported and requires the runtime library to be in the library search 
path.  While it is certainly faster runtime than a perl or fork/exec
method above they both royally suck...