How can a Java program get its own process ID?

后端 未结 22 2293
梦毁少年i
梦毁少年i 2020-11-22 03:47

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.

相关标签:
22条回答
  • 2020-11-22 04:33

    This is the code JConsole, and potentially jps and VisualVM uses. It utilizes classes from sun.jvmstat.monitor.* package, from tool.jar.

    package my.code.a003.process;
    
    import sun.jvmstat.monitor.HostIdentifier;
    import sun.jvmstat.monitor.MonitorException;
    import sun.jvmstat.monitor.MonitoredHost;
    import sun.jvmstat.monitor.MonitoredVm;
    import sun.jvmstat.monitor.MonitoredVmUtil;
    import sun.jvmstat.monitor.VmIdentifier;
    
    
    public class GetOwnPid {
    
        public static void main(String[] args) {
            new GetOwnPid().run();
        }
    
        public void run() {
            System.out.println(getPid(this.getClass()));
        }
    
        public Integer getPid(Class<?> mainClass) {
            MonitoredHost monitoredHost;
            Set<Integer> activeVmPids;
            try {
                monitoredHost = MonitoredHost.getMonitoredHost(new HostIdentifier((String) null));
                activeVmPids = monitoredHost.activeVms();
                MonitoredVm mvm = null;
                for (Integer vmPid : activeVmPids) {
                    try {
                        mvm = monitoredHost.getMonitoredVm(new VmIdentifier(vmPid.toString()));
                        String mvmMainClass = MonitoredVmUtil.mainClass(mvm, true);
                        if (mainClass.getName().equals(mvmMainClass)) {
                            return vmPid;
                        }
                    } finally {
                        if (mvm != null) {
                            mvm.detach();
                        }
                    }
                }
            } catch (java.net.URISyntaxException e) {
                throw new InternalError(e.getMessage());
            } catch (MonitorException e) {
                throw new InternalError(e.getMessage());
            }
            return null;
        }
    }
    

    There are few catches:

    • The tool.jar is a library distributed with Oracle JDK but not JRE!
    • You cannot get tool.jar from Maven repo; configure it with Maven is a bit tricky
    • The tool.jar probably contains platform dependent (native?) code so it is not easily distributable
    • It runs under assumption that all (local) running JVM apps are "monitorable". It looks like that from Java 6 all apps generally are (unless you actively configure opposite)
    • It probably works only for Java 6+
    • Eclipse does not publish main class, so you will not get Eclipse PID easily Bug in MonitoredVmUtil?

    UPDATE: I have just double checked that JPS uses this way, that is Jvmstat library (part of tool.jar). So there is no need to call JPS as external process, call Jvmstat library directly as my example shows. You can aslo get list of all JVMs runnin on localhost this way. See JPS source code:

    0 讨论(0)
  • 2020-11-22 04:36

    It depends on where you are looking for the information from.

    If you are looking for the information from the console you can use the jps command. The command gives output similar to the Unix ps command and comes with the JDK since I believe 1.5

    If you are looking from the process the RuntimeMXBean (as said by Wouter Coekaerts) is probably your best choice. The output from getName() on Windows using Sun JDK 1.6 u7 is in the form [PROCESS_ID]@[MACHINE_NAME]. You could however try to execute jps and parse the result from that:

    String jps = [JDK HOME] + "\\bin\\jps.exe";
    Process p = Runtime.getRuntime().exec(jps);
    

    If run with no options the output should be the process id followed by the name.

    0 讨论(0)
  • 2020-11-22 04:38

    Here is my solution:

    public static boolean isPIDInUse(int pid) {
    
            try {
    
                String s = null;
                int java_pid;
    
                RuntimeMXBean rt = ManagementFactory.getRuntimeMXBean();
                java_pid = Integer.parseInt(rt.getName().substring(0, rt.getName().indexOf("@")));
    
                if (java_pid == pid) {
                    System.out.println("In Use\n");
                    return true;
                }
            } catch (Exception e) {
                System.out.println("Exception:  " + e.getMessage());
            }
            return false;
        }
    
    0 讨论(0)
  • 2020-11-22 04:39

    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();
    
    0 讨论(0)
提交回复
热议问题