Accessing a remote MBean server
Asked Answered
H

5

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.

Haden answered 13/8, 2009 at 5:30 Comment(0)
S
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

Sheldonshelduck answered 13/8, 2009 at 7:46 Comment(0)
P
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);
    }
   }
}
Pl answered 31/8, 2010 at 20:0 Comment(1)
Just having the JMX service URL solved my problem - thanks!Cuman
S
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

Sheldonshelduck answered 13/8, 2009 at 7:46 Comment(0)
C
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 (...) { }
Copenhagen answered 13/8, 2009 at 6:18 Comment(0)
P
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

Paschal answered 13/8, 2009 at 6:12 Comment(2)
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.Haden
Apologies - it wasn't clear from your question that programmatic access was a requirementPaschal
H
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.

Hircine answered 16/4, 2018 at 14:26 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.