javaspringjmxspring-jmx

meaning of valid bean in spring's JMX framework and ways to create a valid bean for autodetect of MBeanExporter


I'm new with spring and I'm currently learning about jmx support that spring provides. I understand that MBeanExporter is one of the core classes of spring's JMX framework. So I was trying to play around with it. (I'm following the tutorial provided here)

I'm trying to experiment with autodetect property of MBeanExporter. But I don't really know whether I understand it correctly or not.

The docs in the link here says that

If autodetect is enabled, then valid JMX-beans will automatically be registered by spring.

Now I don't understand what is actually meant be valid-jmx bean. I understand that every jmx-bean should have an object name and it should implement an interface whose name should be the name of class suffixed with "MBean". Is there any other restriction that I'm missing?

The autodetect functionality of MBeanExporter works good when I satisfy these two restrictions. But I feel that using spring there must be some other ways to construct valid jmx-bean which I'm not aware of. Can you please point me to that?

The following is the code:

application-context.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="mBenaServer" class="org.springframework.jmx.support.MBeanServerFactoryBean">
        <property name="locateExistingServerIfPossible" value="true"/>
    </bean>

    <bean id="exporter" class="org.springframework.jmx.export.MBeanExporter" lazy-init="false">
        <property name="server" ref="mBenaServer"/>
        <!--<property name="beans">-->
            <!--<map>-->
                <!--<entry key="com.mybean:name=testBean1" value-ref="personBean"/>-->
            <!--</map>-->
        <!--</property>-->
        <property name="autodetect" value="true"/>
    </bean>

    <bean id="personBean" class="com.jmx.trial.Person" lazy-init="true">
        <property name="name" value="Lavish"/>
        <property name="age" value="25"/>
    </bean>

</beans>

PersonMBean.java

package com.jmx.trial;

public interface PersonMBean {
    void setName(String name);
    void setAge(int age);
    String getName();
    int getAge();
}

Person.java

package com.jmx.trial;

import org.springframework.jmx.export.naming.SelfNaming;

import javax.management.MalformedObjectNameException;
import javax.management.ObjectName;

public class Person implements PersonMBean, SelfNaming {
    private String name;
    private int age;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public ObjectName getObjectName() throws MalformedObjectNameException {
        return new ObjectName("custom.bean:name=testbean");
    }
}

Main.java

package com.jmx.trial;

import org.apache.log4j.Logger;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Main {
    private static Logger logger = Logger.getLogger(Main.class);

    public static void main(String[] args) throws Exception {
        ApplicationContext context = new ClassPathXmlApplicationContext("context.xml");

        Person p = (Person) context.getBean("personBean");
        System.out.println(p.getName());
        System.out.println(p.getAge());

        logger.debug("Started, now waiting");
        Thread.sleep(Long.MAX_VALUE);
    }
}

I'm looking for whether it is possible to create a valid jmx-bean in any way other than what I've in the above code.

I don't know if it is related to ManagedResource. If yes, then I'd like to have pointers to detailed explanation of that. I tried reading about it on spring/docs but that didn't go smooth for me.


Solution

  • Read the spring documentation.

    Spring adds a layer on top of traditional JMX.

    With traditional JMX, an MBean is a bean, say Foo, with an interface of exposed attributes and operations FooMBean.

    autDetect in this context simply means to automatically detect such interfaces on any beans declared in the application context, and register them.

    Spring allows any bean to be exposed as an MBean (it does not require the interface). Instead, you choose one of several mechanisms to select which attributes/operations are exposed but, in general, you have to tell the exporter which beans you want exposed. You probably never want every bean in an application context to be exposed.

    The annotated model is probably the simplest (@ManagedResource with @ManagedAttribute, @ManagedOperation).

    The AutodetectCapableMBeanInfoAssembler implementation provided by the framework detects these annotations.

    To simplify configuration even further, Spring includes the AutodetectCapableMBeanInfoAssembler interface, which extends the MBeanInfoAssembler interface to add support for autodetection of MBean resources. If you configure the MBeanExporter with an instance of AutodetectCapableMBeanInfoAssembler, it is allowed to “vote” on the inclusion of beans for exposure to JMX.

    The only implementation of the AutodetectCapableMBeanInfo interface is the MetadataMBeanInfoAssembler, which votes to include any bean that is marked with the ManagedResource attribute. ...

    But you can write your own if you want even more auto-detection.