Using jps to Find JVM Process Information

Posted on April 25, 2007 by Scott Leberknight

Recently I wrote a little Rails app that allows people to remotely start/stop/restart CruiseControl and view the output logs on my development workstation, since people don't have access to my workstation directly and from time to time we've had CruiseControl hang for some reason or another. (The shared resource that was available for running CruiseControl is totally overloaded with processes and was taking an hour to run a complete build with tests and code analysis reports while it takes about nine minutes on my machine, so we've decided to keep it on my machine!) Anyway, to control the process I needed to first find the CruiseControl process.

The first iteration used the ntprocinfo tool combined with a simple grep to find all "java.exe" processes running on the machine. This is obviously crap since it only works consistently and correctly if CruiseControl is the only java process running. The I remembered a tool that Matt had showed me a while back to list all the JVMs running on a machine called jps - the Java Virtual Machine Process Status Tool.

This tool was introduced in JDK 1.5/5.0 (or whatever it's called) and lists all the instrumented JVMs currently running on localhost or a remote machine. By default (no command line options) the output shows the local VM identifier (lvmid) and a short form of the class name or JAR file that the VM was started from on the local machine. The lvmid is normally the operating system's process identifier for the JVM. For example:

C:\dev\jps
624 startup.jar
3508 startup.jar
3348 Jps
2444 CruiseControlWithJetty

This is just what I want since now I can do a simple grep on this output and find which process is the CruiseControl process, and then I can use ntprocinfo to kill the process. Easy.

There are command line switches that provide more process detail such as the fully qualified class name (FQCN) or full path to the application JAR file, the arguments to the main method, and JVM arguments. For example, the "l" switch (a lowercase L) gives the FQCN or full path to the class or JAR:

C:\dev\jps -l
624 C:\dev\eclipse\startup.jar
3508 C:\dev\radrails\startup.jar
1948 sun.tools.jps.Jps
2444 CruiseControlWithJetty

Or, the "l" option combined with the "v" option lists FQCN/JAR file and the VM arguments:

C:\dev\jps -lv
624 C:\dev\eclipse\startup.jar -Xms256M -Xmx512M
3508 C:\dev\radrails\startup.jar
1316 sun.tools.jps.Jps -Dapplication.home=C:\dev\java\jdk1.5.0_10 -Xms8m
2444 CruiseControlWithJetty -Xms128m -Xmx256m -Djavax.management.builder.initial=mx4j.server.MX4JMBeanServerBuilder

You can also list the java processes on a remote host, though that machine must have a jstatd process running.

Last but not least, I saw the following warnings in the jps documentation.

  • "This utility is unsupported and may not be available in future versions of the JDK."
  • "You are advised not to write scripts to parse jps output since the format may change in future releases. If you choose to write scripts that parse jps output, expect to modify them for future releases of this tool."

Oh well, nothing is forever, right? By the time thet get around to changing the output format or removing this very useful tool, we'll hopefully have obtained a decent shared build machine where CruiseControl doesn't hang up and which everyone has access to be able to fix any problems if they should arise. As to why CruiseControl hangs up sometimes, I have no idea.



Comments:

Hi,i have some question ask for you,i want to list the java processes on a remote linux host,but when i use the command " jstatd -J-Djava.security.policy=jstatd.all.policy" to start jstatd processe i got this exception message:
-----------------------
Could not bind /JStatRemoteHost to RMI Registry
java.rmi.ConnectIOException: non-JRMP server at remote endpoint
at sun.rmi.transport.tcp.TCPChannel.createConnection(TCPChannel.java:217)
at sun.rmi.transport.tcp.TCPChannel.newConnection(TCPChannel.java:171)
at sun.rmi.server.UnicastRef.newCall(UnicastRef.java:306)
at sun.rmi.registry.RegistryImpl_Stub.rebind(Unknown Source)
at java.rmi.Naming.rebind(Naming.java:160)
at sun.tools.jstatd.Jstatd.bind(Jstatd.java:40)
at sun.tools.jstatd.Jstatd.main(Jstatd.java:126)
-------------------------
So I changed to port 1982 because I read somewhere that JBoss binds the naming to 1099,code like this:
#rmiregistry 1982&
#jstatd -J-Djava.security.policy=jstatd.all.policy -p 1982
this time jstatd processe can be started,but use "jps -m 192.168.0.102:1982" cannot find JVM process information but got this message "Malformed Host Identifier: 192.168.0.102:1982".I've tried to run jstatd on my windows xp machine, but i didn't find any problems.
How could i solve this problem? Thank you!

Posted by david.tao on April 28, 2007 at 01:28 AM EDT #

Post a Comment:
Comments are closed for this entry.