How can a Java program get its own process ID?

后端 未结 22 2325
梦毁少年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 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:

提交回复
热议问题