My name is Philipp C. Heckel and I write about nerdy things.

Snippet 0x02: Getting the Java process PID and managing PID files (Linux/Windows)


Code Snippets, Programming

Snippet 0x02: Getting the Java process PID and managing PID files (Linux/Windows)


To the best of my knowledge, Java doesn’t offer a good way to get the OS-dependent PID of its own process. Sure, there are libraries to do that — but do you really want to add a heavy library for this simple task? Well I didn’t. Syncany already has so many dependencies, I don’t want to introduce a new one just for this simple task.


Content


Updates

Check out the method described by Toma in the comments. He suggests picking a port and writing the port number to a file, then checking the port through the scripts/batch files.

1. A simple PidFileUtil!

This tutorial basically explains the class PidFileUtil I wrote and used for Syncany. The class offers the following public methods:

If you don’t care how it works, go ahead and grab the class and you’re good to go. If you’re interested. Read along.

2. Getting the Java process PID

I found two ways to get the process PID while searching around. StackOverflow had my back, as always!

The first method (as found on SO) uses the name of the RuntimeMXBean (i.e. the getName() method). On Linux, this name typically has a value like 12345@localhost where 12345 is the PID. However, this is not guaranteed for every VM, so this is only one of two implementations.

If this method fails, here’s another method (also found on SO): This implementation uses the private method VMManagement.getProcessId() of Sun’s sun.management.VMManagement class to determine the PID. Since this is a private method of an internal class, however, we first need to make the the relevant fields accessible using the power of reflection. This is obviously really sketchy, because as soon as the implementation fails (or fields are renamed), this method won’t work anymore — it’s the best we’ve got though …

Using Class.getDeclaredField("jvm"), we first obtain the Field that holds the VMManagement object — a field of the RuntimeImpl class, an implementation of RuntimeMXBean.

From this field, we get the actual object using get(). There is no need to cast the object to VMManagement since we’ll only use reflection to call methods anyhow — and that avoids IDE warnings of internal classes.

These two methods can now be orchestrated into a single public method getProcessPid(). This method first tries the first implementation, and if that does not succeed, try the next one. To create a PID file from this information, the createPidFile() can be used.

3. Check if process is running

To check if your program is already runnning, you have to read the PID file and see if the process is still active. So after finding the PID of the Java process (and using it to write a PID file), the next thing we want to do is do just that.

Again, there is no Java/JVM standard way to do that, but it can be done with Linux/Windows commands. On Linux, the kill -0 <pid> command can be used. Contrary to its name, this command (at least when sending the 0-signal) does not kill the process, but only returns its state. If the exit code is 0, the process is running. If not, it’s not:

On Windows, we can use the tasklist command to see if a process with our PID is still running. Using the filter PID eq <pid>, we can tell the command to only output processes with this PID:

A. About this post

I’m trying a new section for my blog. I call it Code Snippets. It’ll be very short, code-focused posts of things I recently discovered or find fascinating or helpful. I hope this helps.

2 Comments

  1. Toma

    jEdit solves above server singelton problem by opening an socket and writing the port number into a file.
    Every new instance tries to connect to this port and after some handshaking the new process terminates, if a server is already running or the new process wins if the old one died after some timeout.
    This is much easier to do in Java. Still some races are possible, like starting two severs with different port file…


  2. Philipp C. Heckel

    Also an interesting method and probably easier to implement. Not sure how to check if a port is open on Windows… Ahh, SO helps again: http://stackoverflow.com/a/10315609/1440785

    Thanks for the idea. Maybe I’ll switch to that for Syncany. Sounds a lot easier and not VM-dependent!