I am running a client/server application using JBoss.
How can I connect to the server JVM's MBeanServer? I want to use the MemoryMX MBean to track the memory consumption.
I can connect to the JBoss MBeanServer using JNDI lookup but the java.lang.MemoryMX MBean is not registered with the JBoss MBeanServer.
EDIT: The requirement is for programmatic access to the memory usage from the client.
Unlike the JBoss server's MBeanServer, the JVM's MBean server doesn't allow remote monitoring by default. You need to set various system properties to allow that:
http://java.sun.com/javase/6/docs/technotes/guides/management/agent.html
I wrote a class like this:
import javax.management.remote.JMXServiceURL;
import javax.management.MBeanAttributeInfo;
import javax.management.MBeanInfo;
import javax.management.MBeanServerConnection;
import javax.management.ObjectName;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
public class JVMRuntimeClient
{
static void main(String[] args) throws Exception
{
if (args == null)
{
System.out.println("Usage: java JVMRuntimeClient HOST PORT");
}
if(args.length < 2)
{
System.out.println("Usage: java JVMRuntimeClient HOST PORT");
}
try
{
JMXServiceURL target = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://"+args[0]+":"+args[1]+"/jmxrmi");
JMXConnector connector = JMXConnectorFactory.connect(target);
MBeanServerConnection remote = connector.getMBeanServerConnection();
/**
* this is the part where you MUST know which MBean to get
* com.digitalscripter.search.statistics:name=requestStatistics,type=RequestStatistics
* YOURS WILL VARY!
*/
ObjectName bean = new ObjectName("com.digitalscripter.search.statistics:name=requestStatistics,type=RequestStatistics");
MBeanInfo info = remote.getMBeanInfo(bean);
MBeanAttributeInfo[] attributes = info.getAttributes();
for (MBeanAttributeInfo attr : attributes)
{
System.out.println(attr.getDescription() + " " + remote.getAttribute(bean,attr.getName()));
}
connector.close();
}
catch(Exception e)
{
System.out.println(e.getMessage());
System.exit(0);
}
}
}
A code example from an IBM article: link
MBeanServerConnection serverConn;
try {
//connect to a remote VM using JMX RMI
JMXServiceURL url = new JMXServiceURL( "service:jmx:rmi:///jndi/rmi://<addr>");
JMXConnector jmxConnector = JMXConnectorFactory.connect(url);
serverConn = jmxConnector.getMBeanServerConnection();
ObjectName objName = new
ObjectName(ManagementFactory.RUNTIME_MXBEAN_NAME);
// Get standard attribute "VmVendor"
String vendor =
(String) serverConn.getAttribute(objName, "VmVendor");
} catch (...) { }
Have you tried launching a JConsole
(is $JAVA_HOME/bin
) to connect with the server? You should be able to view memory stats from there
The following code lists all mbeans of a given (jmx enabled) java application with their attributes and operations grouped by the domain. Just start the java app you wanna monitor with a fixed jmx port, e.g. by using these vm parameters:
-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.port=9000
-Dcom.sun.management.jmxremote.local.only=false
-Dcom.sun.management.jmxremote.ssl=false
-Dcom.sun.management.jmxremote.authenticate=false
Then run this main:
import javax.management.*;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;
import java.io.IOException;
public class JmxListAll {
public static void main(String[] args) throws IOException, MalformedObjectNameException, IntrospectionException, InstanceNotFoundException, ReflectionException {
/*
1. JMXServiceURL.
*/
String jmxHost = "localhost:9000"; // exactly like jconsole localhost:9026
String url = "service:jmx:rmi:///jndi/rmi://" + jmxHost + "/jmxrmi";
JMXServiceURL serviceURL = new JMXServiceURL(url);
/*
2. JMXConnector and the actual serverConnection
*/
JMXConnector connector = JMXConnectorFactory.connect(serviceURL);
MBeanServerConnection serverConnection = connector.getMBeanServerConnection();
/*
3. Walk through the domains and their objects
*/
System.out.println("\n Now we have a look at " + serverConnection.getMBeanCount() + " mbeans!");
int objectCount = 0;
for (String domain : serverConnection.getDomains()) {
System.out.println("\n***********************************************************************************");
System.out.println("DOMAIN: " + domain);
// query all the beans for this domain using a wildcard filter
for (ObjectName objectName : serverConnection.queryNames(new ObjectName(domain + ":*"), null)) {
System.out.println(" objectName " + ++objectCount + ": " + objectName);
MBeanInfo info = serverConnection.getMBeanInfo(objectName);
for (MBeanAttributeInfo attr : info.getAttributes()) {
System.out.print(" attr: " + attr.getDescription());
try {
String val = serverConnection.getAttribute(objectName, attr.getName()).toString();
System.out.println(" -> " + abbreviate(val));
} catch (Exception e) {
System.out.println(" FAILED: " + e);
}
}
for (MBeanOperationInfo op : info.getOperations()) {
System.out.println(" op: " + op.getName());
}
}
}
}
static String abbreviate(String text) {
if (text != null && text.length() > 42) {
return text.substring(0, 42) + "...";
} else {
return text;
}
}
}
As you should see, in the java.lang domain are several memory related mbeans. Pick the one you need.
来源:https://stackoverflow.com/questions/1270173/accessing-a-remote-mbean-server