« Mission Control 2.0 released! (Migrated from the old BEA blog) | Main | Unorthodox Uses of the Memory Leak Detection Tool - Part 1 (Migrated from the old BEA blog) »

JRCMD Goes Remote (>=R27.1 edition) (Migrated from the old BEA blog)

This is an updated version of my JRCMD goes remote blog entry. In version R27 JRockit had a major overhaul of the MBeans used to expose JRockit specific manageability features. One major difference is that the JRockit specific features are not loaded into the platform MBean server by default. To load them, a specific MBean must first be created, which in turn will load the rest of the MBeans exposing the API. The MBeans also moved to a new domain: "bea.jrockit.management".

The MBean to load is the bea.jrockit.management:JRockitConsole MBean. This can be done by simply using the MBeanServerConnection, for example like this:

MBeanServerConnection#createMBean(
   "bea.jrockit.management.JRockitConsole", null);

The following example is an altered version of my old "JRCMD Goes Remote" blog that, just like the JRCMD, allows the performance counters and ctrl-break handlers to be read/executed - but remotely from another machine.


import java.lang.management.ManagementFactory;
import java.net.MalformedURLException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import javax.management.Attribute;
import javax.management.InstanceNotFoundException;
import javax.management.MBeanAttributeInfo;
import javax.management.MBeanServerConnection;
import javax.management.ObjectName;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;

/**
* Simple code example on how to execute ctrl-break handlers remotely.
*
* Usage: RemoteJRCMD -host -port -user -pass
* -command []
*
* All arguments are optional. If no command is specified, all performance
* counters and their current values are listed.
*
* @author Marcus Hirt
*/
public class RemoteJRCMD {
private final static String KEY_CREDENTIALS = "jmx.remote.credentials";
private final static String JROCKIT_PERFCOUNTER_MBEAN_NAME = "bea.jrockit.management:type=PerfCounters";
private final static String JROCKIT_CONSOLE_MBEAN_NAME = "bea.jrockit.management:type=JRockitConsole";
private final static String[] SIGNATURE = new String[] { "java.lang.String" };
private final static String DIAGNOSTIC_COMMAND_MBEAN_NAME = "bea.jrockit.management:type=DiagnosticCommand";


public static void main(String[] args) throws Exception {
HashMap commandMap = new HashMap();
commandMap.put("-host", "localhost");
commandMap.put("-port", "7091");
for (int i = 0; i < args.length; i++) {
if (args[i].startsWith("-")) {
StringBuilder buf = new StringBuilder();
int j = i + 1;
while (j < args.length && !args[j].startsWith("-")) {
buf.append(" ");
buf.append(args[j++]);
}
commandMap.put(args[i], buf.toString().trim());
i = j - 1;
}
}
executeCommand((String) commandMap.get("-host"), Integer
.parseInt(commandMap.get("-port")), commandMap.get("-user"), commandMap
.get("-password"), commandMap.get("-command"));
}

public static void executeCommand(String host, int port, String user,
String password, String command) throws Exception {
MBeanServerConnection server = null;
JMXConnector jmxc = null;
Map map = null;
if (user != null || password != null) {
map = new HashMap();
final String[] credentials = new String[2];
credentials[0] = user;
credentials[1] = password;
map.put(KEY_CREDENTIALS, credentials);
}
// Use same convention as Sun. localhost:0 means "VM, monitor thyself!"
if (host.equals("localhost") && port == 0) {
server = ManagementFactory.getPlatformMBeanServer();
} else {
jmxc = JMXConnectorFactory.newJMXConnector(
createConnectionURL(host, port), map);
jmxc.connect();
server = jmxc.getMBeanServerConnection();
}

System.out.println("Connected to " + host + ":" + port);

try {
server.getMBeanInfo(new ObjectName(JROCKIT_CONSOLE_MBEAN_NAME));
} catch (InstanceNotFoundException e1) {
server.createMBean("bea.jrockit.management.JRockitConsole", null);
}

if (command == null) {
ObjectName perfCounterObjectName = new ObjectName(
JROCKIT_PERFCOUNTER_MBEAN_NAME);
System.out.println("Listing all counters...");
MBeanAttributeInfo[] attributes = server.getMBeanInfo(
perfCounterObjectName).getAttributes();
System.out.println("Counter\tValue\n=======\t====");

String[] attributeNames = new String[attributes.length];
for (int i = 0; i < attributes.length; i++) {
attributeNames[i] = attributes[i].getName();
}
Iterator valueIter = server.getAttributes(perfCounterObjectName,
attributeNames).iterator();
while (valueIter.hasNext()) {
Attribute attr = (Attribute) valueIter.next();
System.out.println(attr.getName() + "\t=\t" + attr.getValue());
}
} else {
System.out
.println("Invoking the ctrl-break command '" + command + "'...");
ObjectName consoleObjectName = new ObjectName(DIAGNOSTIC_COMMAND_MBEAN_NAME);
Object[] params = new Object[1];
params[0] = command;
System.out.println("The CtrlBreakCommand returned: \n"
+ server.invoke(consoleObjectName, "execute",
params, SIGNATURE));
}

if (jmxc != null) {
jmxc.close();
}
}

private static JMXServiceURL createConnectionURL(String host, int port)
throws MalformedURLException {
return new JMXServiceURL("rmi", "", 0, "/jndi/rmi://" + host + ":" + port
+ "/jmxrmi");
}
}


The following example would list all the performance counters and their values on localhost on the default port (7091):

java RemoteJRCMD

The following example would start a 60 second JRA recording on a JRockit running at the host bitsy, port 7099, writing the resulting recording to a file called nisse.zip:

java RemoteJRCMD -command jrarecording filename=nisse time=60 -host bitsy -port 7091

And as always, don't forget to enable the JMX management agent of the JRockit you wish to monitor. You can enable the management agent by using the -Xmanagement option like so:

-Xmanagement:port=7091,ssl=false,authenticate=false

TrackBack

TrackBack URL for this entry:
http://blogs.oracle.com/mte1521/mt-tb.cgi/5693

Post a comment

(If you haven't left a comment here before, you may need to be approved by the site owner before your comment will appear. Until then, it won't appear on the entry. Thanks for waiting.)

About This Entry

This page contains a single entry from the blog posted on August 4, 2008 2:52 PM.

The previous post in this blog was Mission Control 2.0 released! (Migrated from the old BEA blog).

The next post in this blog is Unorthodox Uses of the Memory Leak Detection Tool - Part 1 (Migrated from the old BEA blog).

Many more can be found on the main index page or by looking through the archives.

Top Tags

Powered by
Movable Type and Oracle