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.

Rails Without a Database

Posted on April 07, 2007 by Scott Leberknight

Last week I needed to write a simple web application that would allow others on my team to control a process on my workstation when I wasn't around. Essentially I wanted to allow people to start, stop, restart, get process information about, and view the log of, a process running on my workstation. Since I wanted it to be simple, and because I didn't want it to take more than a few hours, I chose to write in in Rails. This turned out to be ridiculously simple, as I ended up with two controllers - an authentication controller and the process controlling controller - along with a few views. But, since all I was doing was calling system commands from the process controlling controller, there is no database in this application. (The "authentication" was just a hardcoded user name and password that I shared with my team so no database stuff there!)

So what happens when you have a Rails application with no database? Well, it works functionally, i.e when you are hacking your controllers and such, but the tests all fail! This is because Rails assumes you always have a database. A quick Google search led to an excellent resource, Rails Recipes, by the Pragmatic Progammers for writing and testing Rails apps with no database. One of the recipes is, conveniently enough, Rails without a Database! Basically, it describes how you can modify the Rails test_helper.rb file to remove all the database-specific setup and teardown code and then you can run your tests with no database to speak about. Cool.