简体   繁体   中英

JMX MXBean Attributes all UNDEFINED - Spring 3.0.x/Tomcat 6.0

I've been trying to get a sample JMX MXBean working in a Spring-configured webapp, but any basic attributes on the MXBean are coming up as UNDEFINED when I connect with jconsole.

Java interface/classes:

public interface IJmxBean { // marker interface for spring config, see below
}

public interface MgmtMXBean { // lexical convention for MXBeans - mgmt interface
    public int getAttribute();
}

public class Mgmt implements IJmxBean, MgmtMXBean { // actual JMX bean
    private IServiceBean serviceBean;    // service bean injected by Spring
    private int attribute = 0;

    @Override
    public int getAttribute() {
        if(serviceBean != null) {
            attribute = serviceBean.getRequestedAttribute();
        }
        return attribute;
    }

    public void setServiceBean(IServiceBean serviceBean) { 
        this.serviceBean = serviceBean;
    }
}

Spring JMX config:

<beans>
    <context:component-scan base-package="...">
        <context:include-filter type="assignable" expression="...IJmxBean" />
    </context:component-scan>
    <context:mbean-export />
</beans>

Here's what I know so far:

  • The element is correctly instantiating a bean named "mgmt". I've got logging in a zero-argument public constructor that indicates it gets constructed.

  • is correctly automatically detecting and registering the MgmtMXBean interface with my Tomcat 6.0 container. I can connect to the MBeanServer in Tomcat with jconsole and drill down to the Mgmt MXBean.

  • When examining the MXBean, "Attribute" is always listed as UNDEFINED, but jconsole can tell the correct type of the attribute. Further, hitting "Refresh" in jconsole does not actually invoke the getter method of "Attribute"- I have logging in the getter method to indicate if it is being invoked (similar to the constructor logging that works) and I see nothing in the logs.

At this point I'm not sure what I'm doing wrong. I've tried a number of things, including constructing an explicit Spring MBeanExporter instance and registering the MXBean by hand, but it either results in the MBean/MXBean not getting registered with Tomcat's MBean server or an Attribute value of UNDEFINED.

For various reasons, I'd prefer not to have to use Spring's @ManagedResource/@ManagedAttribute annotations.

Is there something that I'm missing in the Spring docs or MBean/MXBean specs?

ISSUE RESOLVED: Thanks to prompting by Jon Stevens (above), I went back and re-examined my code and Spring configuration files:

Throwing an exception in the getAttribute() method is a sure way to get "Unavailable" to show up as the attribute's value in JConsole. In my case:

  • The Spring JMX config file I was using was lacking the default-autowire="" attribute on the root <beans> element;
  • The code presented above checks to see if serviceBean != null . Apparently I write better code on stackoverflow.com than in my test code, since my test code wasn't checking for that. Nor did I have implements InitializingBean or @PostConstruct to check for serviceBean != null like I normally do on almost all the other beans I use;
  • The code invoking the service bean was before the logging, so I never saw any log messages about getter methods being entered;
  • JConsole doesn't report when attribute methods throw exceptions;
  • The NPE did not show up in the Tomcat logs.

Once I resolved the issue with serviceBean == null , everything worked perfectly. Regardless, +1 to Jon for providing a working demo, since there are literally 50 different ways to configure MBeans/MXBeans within Spring.

I've recently built a sample Spring based webapp that very cleanly enables JMX for latest versions of Spring, Hibernate and Ehcache.

It has examples for both EntityManager based access and DAO access (including transactions!). It also shows how to do annotation based injection in order to negate having to use Spring's xml config for beans. There is even a SpringMVC based example servlet using annotations. Basically, this is a Spring based version of a fairly powerful application server running on top of any servlet engine.

It isn't documented yet, but I'll get to that soon. Take a look at the configuration files and source code and it should be pretty clear.

The motivation behind this is that I got tired of all of the crazy blog posts with 50 different ways to set things up and finally made a single simple source that people can work from. It is up on github so feel free to fork the project and do whatever you want with it.

https://github.com/lookfirst/fallback

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM