How to Get Started with JConsole Plugins
Join the DZone community and get the full member experience.
Join For FreeThe 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.
Opinions expressed by DZone contributors are their own.
Comments