How can a Java program get its own process ID?

312,836

Solution 1

There exists no platform-independent way that can be guaranteed to work in all jvm implementations. ManagementFactory.getRuntimeMXBean().getName() looks like the best (closest) solution, and typically includes the PID. It's short, and probably works in every implementation in wide use.

On linux+windows it returns a value like "12345@hostname" (12345 being the process id). Beware though that according to the docs, there are no guarantees about this value:

Returns the name representing the running Java virtual machine. The returned name string can be any arbitrary string and a Java virtual machine implementation can choose to embed platform-specific useful information in the returned name string. Each running virtual machine could have a different name.

In Java 9 the new process API can be used:

long pid = ProcessHandle.current().pid();

Solution 2

You could use JNA. Unfortunately there is no common JNA API to get the current process ID yet, but each platform is pretty simple:

Windows

Make sure you have jna-platform.jar then:

int pid = Kernel32.INSTANCE.GetCurrentProcessId();

Unix

Declare:

private interface CLibrary extends Library {
    CLibrary INSTANCE = (CLibrary) Native.loadLibrary("c", CLibrary.class);   
    int getpid ();
}

Then:

int pid = CLibrary.INSTANCE.getpid();

Java 9

Under Java 9 the new process API can be used to get the current process ID. First you grab a handle to the current process, then query the PID:

long pid = ProcessHandle.current().pid();

Solution 3

Here's a backdoor method which might not work with all VMs but should work on both linux and windows (original example here):

java.lang.management.RuntimeMXBean runtime = 
    java.lang.management.ManagementFactory.getRuntimeMXBean();
java.lang.reflect.Field jvm = runtime.getClass().getDeclaredField("jvm");
jvm.setAccessible(true);
sun.management.VMManagement mgmt =  
    (sun.management.VMManagement) jvm.get(runtime);
java.lang.reflect.Method pid_method =  
    mgmt.getClass().getDeclaredMethod("getProcessId");
pid_method.setAccessible(true);

int pid = (Integer) pid_method.invoke(mgmt);

Solution 4

Try Sigar . very extensive APIs. Apache 2 license.

private Sigar sigar;

public synchronized Sigar getSigar() {
    if (sigar == null) {
        sigar = new Sigar();
    }
    return sigar;
}

public synchronized void forceRelease() {
    if (sigar != null) {
        sigar.close();
        sigar = null;
    }
}

public long getPid() {
    return getSigar().getPid();
}

Solution 5

The following method tries to extract the PID from java.lang.management.ManagementFactory:

private static String getProcessId(final String fallback) {
    // Note: may fail in some JVM implementations
    // therefore fallback has to be provided

    // something like '<pid>@<hostname>', at least in SUN / Oracle JVMs
    final String jvmName = ManagementFactory.getRuntimeMXBean().getName();
    final int index = jvmName.indexOf('@');

    if (index < 1) {
        // part before '@' empty (index = 0) / '@' not found (index = -1)
        return fallback;
    }

    try {
        return Long.toString(Long.parseLong(jvmName.substring(0, index)));
    } catch (NumberFormatException e) {
        // ignore
    }
    return fallback;
}

Just call getProcessId("<PID>"), for instance.

Share:
312,836
Steve
Author by

Steve

linkedin

Updated on July 08, 2022

Comments

  • Steve
    Steve almost 2 years

    How do I get the id of my Java process?

    I know there are several platform-dependent hacks, but I would prefer a more generic solution.

  • Brad Mace
    Brad Mace over 11 years
    You'd have a lot more upvotes if you explained how to use SIGAR for this
  • Drupad Panchal
    Drupad Panchal over 11 years
    very nice, just verified that it works both on the JRockit as well as the Hotspot JVMs.
  • ATorras
    ATorras about 11 years
    +1 But I'm afraid that in a security constrained environment it should not work (tomcat, WebLogic, etc.).
  • Espinosa
    Espinosa almost 11 years
    VisualVM uses similar code to get self PID, check com.sun.tools.visualvm.application.jvm.Jvm#ApplicationSuppor‌​t#createCurrentAppli‌​cation(). They are the experts, so it looks like dependable, cross platform solution.
  • Espinosa
    Espinosa almost 11 years
    JPS tool uses jvmstat library, part of tools.jar. Check my example or see JPS source code: grepcode.com/file_/repository.grepcode.com/java/root/jdk/…. There is no need to call JPS as external process, use jvmstat library directly.
  • fragorl
    fragorl about 10 years
    Nice workaround. I'm going to assume there is a good reason why this method (and others in the class) aren't public and easily accessible, and I'm curious to know what it is.
  • Michael Klishin
    Michael Klishin about 10 years
    This solution is really fragile. See an answer about Hyperic Sigar below.
  • Rich
    Rich about 10 years
    If you're calling shell scripts, you might as well do something simpler like bash -c 'echo $PPID' or the /proc answers above
  • hfontanez
    hfontanez over 9 years
    Oracle Java team have announced that they intend to hide all non-java packages (i.e. sun.*) I believe starting with Java 10 (scheduled for 2018 - maybe Java 9). If you have a similar implementation as the one above, you may want to figure out an alternative so that your code don't break.
  • Aquarius Power
    Aquarius Power about 9 years
    that pid is good to write on a lock file as stackoverflow.com/a/9020391/1422630
  • Steve
    Steve almost 9 years
    Wow, that was fast. It only took about seven years! 😃
  • Augusto
    Augusto over 8 years
    Can you explain how to get a Process instance for the current running process in Java 9?
  • Mike Stoddart
    Mike Stoddart over 8 years
    Doesn't work for me either as the sun.* packages are probably removed or inaccessible (VMManagement cannot be resolved to a type).
  • crazyGuy
    crazyGuy about 8 years
    Great answer for using Java 9 in 2016! Can you add a link to the javadocs? thanks
  • Daniel Widdis
    Daniel Widdis almost 8 years
    The getpid() solution also works for OS X, with a JNA call to the "System" library.
  • Panayotis
    Panayotis almost 8 years
    Is it possible to get the PID of a Process started by Java? Or start a Process "your way" to fix this issue?
  • c0der
    c0der over 7 years
    This does not check if pid is in use, but if pid equals current process pid
  • PartialData
    PartialData over 7 years
    What is the correct solution so i can update my code?
  • Narendra Parmar
    Narendra Parmar over 7 years
    if mainClass.getName() does not work try to use mainClass.getCanonicalName();
  • david.perez
    david.perez about 7 years
    In my case with Ubuntu 16.04 and Java 8, it returns null
  • Jules
    Jules over 6 years
    Link is broken. You give an example of how to use this, but is there a maven dependency for it?
  • skytree
    skytree over 6 years
    However, I get error: cannot find symbol for jdk9
  • Zastai
    Zastai over 5 years
    github.com/hyperic/sigar seems to be a usable location; this also shows that it's native code with Java bindings, which may make it less of a solution for many contexts.
  • Andrew T Finnell
    Andrew T Finnell about 5 years
    Due to the way reflection works, access to sun.management.* is not needed. Just perform the getDeclaredMethod on the Object returned by jvm.get(runtime).
  • matbrgz
    matbrgz about 4 years
    @Espinosa VisualVM only supportes running on a OpenJDK/Oracle/GraalVM JVM (as of 2020). This mean they can make assumptions accordingly. If you do the same, you become vendor dependent and your code may break if running on for instance J9.
  • Seth Tisue
    Seth Tisue over 3 years
    (looks good for Linux and macOS, but I don't know if it would work on Windows)
  • toolforger
    toolforger almost 2 years
    Starting an entire new subprocess just to get the PID which is already available in the process itself is pretty overblown. Also, this won't work on Windows since it has no "sh" command (usually).