Geertjan is a DZone Zone Leader and has posted 460 posts at DZone. You can read more from them at their website. View Full User Profile

How to Get Started with JConsole Plugins

01.28.2008
| 29232 views |
  • submit to reddit
While reading Beginning Java SE 6 Platform: From Novice to Professional, I discovered for the first time that the JConsole is pluggable, since Java SE 6. That's maybe not exactly news, if you're a friend of JConsole and have followed its adventures over the past years. Personally, I'm more interested in JConsole's pluggability than JConsole itself.

The JDK provides a set of demos, some of which are helpful in understanding how plugins work in relation to JConsole. Go to demo/management in the JDK's installation folder and you'll find them. Especially JTop is helpful in showing how a new panel can be added to the JConsole. The panel is simply a JPanel. In addition to the JPanel, you need a class that extends JConsolePlugin, which uses its getTabs method to retrieve the JPanel. From page 245 of the abovementioned book, you get a brilliant exposition of everything related to the JConsole's pluggability. (Here's hoping that the same author will get to write the book on Java SE 7.) Mandy Chung's blog, which is referenced in the book above, is also great in its discussion of the JConsole and its pluggability.

In my first experiment, I added a web browser to JConsole. That was kind of fun, though I wasn't interacting with any of the data provided by the JConsole. Here is my second experiment, which is more interesting, providing a visual thread window in the JConsole:

The visual part of the above JConsole plugin is provided by the NetBeans Visual Library API. Whenever I detect a thread name, I create a new node on the canvas. When I detect a new state or a new ID, I create a pin, which is the info below the thread name in the screenshot above. Here's the code for that part:

void setThreadList(List<Entry<Long, ThreadInfo>> list, DemoGraphScene scene, MBeanServerConnection server) {
threadList = list;
for (int i = 0; i < threadList.size(); i++) {
String text = threadList.get(i).getValue().getThreadName();
String state = threadList.get(i).getValue().getThreadState().name();
Long threadId = threadList.get(i).getValue().getThreadId();
createNode(scene, (int) (300), (int) (300), text, "Value", null);
createPin(this, text, text + ":" + state, "State: " + state, null);
createPin(this, text, text + ":" + threadId, "Id: " + threadId, null);
}
this.moveTo(null);
}

Here are the three methods used for creating the nodes and pins, as well as the movement which positions the nodes on the canvas:

private String createNode(DemoGraphScene scene, int x, int y, String name, String type, java.util.List<Image> glyphs) {
String nodeID = name;
if (!scene.getNodes().contains(nodeID)) {
VMDNodeWidget widget = (VMDNodeWidget) scene.addNode(nodeID);
widget.setPreferredLocation(new Point(x, y));
widget.setNodeProperties(null, name, type, glyphs);
}
return nodeID;
}

private static void createPin(DemoGraphScene scene, String nodeID, String pinID, String name, String type) {
if (!scene.getPins().contains(pinID)) {
((VMDPinWidget) scene.addPin(nodeID, pinID)).setProperties(name, null);
}
}

private void moveTo(Point point) {
int index = 0;
for (String node : getNodes()) {
getSceneAnimator().animatePreferredLocation(findWidget(node), point != null ? point : new Point(100, ++index * 100));
}
}

All of the above is in a class that extends VMDGraphScene. And that's most of the plugin, the rest is pretty much the same as the JTop demo plugin that you can find in the JDK's installation folder. It's pretty cool that one can now extend the JConsole, gives you a lot of room to manouevre.

Once you've created a JAR that contains your plugin, you need to start the JConsole together with the --pluginpath command line argument. And the value of the argument is the location of the JAR. I normally start up the JConsole from an Ant script that overrides the application's Run target. The application isn't able to run anyway, since it is a plugin, so the Run target is useless. So, I've given it some purpose by using it to start JConsole, together with my plugin:

    <target name="run">
<exec dir="../../../bin" executable="jconsole">
<arg value="-pluginpath"/>
<arg value="..demo/management/VMDDemoPlugin/dist/VMDDemoPlugin.jar"/>
</exec>
</target>

Then, because you've created a META-INF/services folder, as shown in the JTop sample, and because of the abovementioned class that extends JConsolePlugin, a new tab is added to the JConsole, as defined by your JPanel.

 

Published at DZone with permission of its author, Geertjan Wielenga.