11

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.

5 Answers 5

18

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); } } } 
Sign up to request clarification or add additional context in comments.

1 Comment

Just having the JMX service URL solved my problem - thanks!
6

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

Comments

4

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 (...) { } 

Comments

1

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

2 Comments

Yes, that works. But I want programmatic access from my client application. My client can connect to the JBoss MBean server, but I don't know how to connect to the platform MBean server.
Apologies - it wasn't clear from your question that programmatic access was a requirement
1

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.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.