Skip navigation

Big applications have a tendency to accumulate enormous classpaths. Looking at such a classpath, you might be hard put to know whether any given jar is really needed. Perhaps it was needed at the time it was added, but that need has long since evaporated. How can you tell? Having jars you don't need means your application will be slower starting up, and perhaps also while running. It also means that you might be worrying unnecessarily about getting the latest version of a jar that you're not actually using.

Kyrill Alyoshin has an elegant solution using a java.lang.instrument agent. The basic idea is that you run your application with java -javaagent:loosejar.jar ... and the agent in loosejar.jar can find all the classes that the application has loaded using Instrumentation.getAllLoadedClasses(). Then for each of those classes it can find what jar it came from. Thus for each jar on the classpath it can compute the number of classes that have actually been loaded from it. When this number is zero, the jar might be unnecessary.

Of course for the results to be valid you have to exercise the application so that it does everything it can do. That might not always be easy, but for a candidate jar you can often figure out what to do to make the jar be referenced. To help you do this incrementally, the loosejar agent exports a JMX MBean that allows you to ask for a report while the application is running. So you can connect with JConsole and get a report, see what jars might be unnecessary, try to provoke class-loading from those jars, get another report, and so on.

One subtlety is that the set of jars is not just the contents of the classpath. The jar could reference other jars through a Class-Path entry in its manifest. You'd like to know if all of those other jars are really necessary too. Kyrill and I were unable to find a better way to get the transitive closure of referenced jar files than to use ClassLoader.getResources("META-INF/MANIFEST.MF") and parse the returned jar: URLs. Every jar has aMETA-INF/MANIFEST.MF file, so every jar known by the ClassLoader will show up in the result of this call, but ugh. There has to be a better way.

Kyrill's loosejar project is hosted on Google Code.

VisualVM is a new graphical troubleshooting tool that is being developed in a project on It gives access to the functionality that is available through existing JDK tools such as JConsole, jinfo, and jstack, and adds to that support for lightweight profiling of CPU and memory usage.

These screenshots from the project page give an idea of what the tool can do.

Basic telemetry of running Java app Profiling performance of running Java app 

The tool is extensible via downloadable plugins, and the latest milestone publishes an API for developing your own plugins. Also, if you have developed plugins using the JConsole Plugin API it's possible to use them unchanged in VisualVM.

I'm not personally involved in this project but I'm certainly following it with great interest.

[Tags: visualvm.]

The Public Review of JSR 262, "Web Services Connector for JMX Agents", is underway, and there's a new snapshot of the Reference Implementation that corresponds to the Public Review specification.

Jean-François's blog has the full details.

[Tags: jmx jsr262 ws-management.]