Creating MBean in Java

Biscuit128 picture Biscuit128 · Aug 14, 2014 · Viewed 14.4k times · Source

I am trying to make a class implement an MBean Interface so I can interrogate the properties at runtime. The class I am trying to interrogate is as follows

public class ProfileCache implements ProfileCacheInterfaceMBean{

    private Logger logger = Logger.getLogger(ProfileCache.class);
    private ConcurrentMap<String, Profile> cache;


    public ProfileCache(ConcurrentMap<String, Profile> cache){
        this.cache = cache;     
    }

    /**
     * Update the cache entry for a given user id
     * @param userid the user id to update for 
     * @param profile the new profile to store
     * @return true if the cache update
     */
    public boolean updateCache(String userid, Profile profile) {
        if (cache == null || cache.size() == 0) {
            throw new RuntimeException("Unable to update the cache");
        }
        if (cache.containsKey(userid)) {
            if (profile != null) {
                cache.put(userid, profile);
                logger.info("Updated the cache for user: "
                            + userid + "  profile: " + profile);
                return true;
            }
        }
        return false;
    }

    @Override
    public ConcurrentMap<String, Profile> getCache() {
        if(cache == null){
            cache = new ConcurrentHashMap<String, Profile>();
        }
        return cache;
    }


}

The interface looks like this

import com.vimba.profile.Profile;

public interface ProfileCacheInterfaceMBean {

    ConcurrentMap<String, Profile> getCache();

}

And i start the MBean like this

        cacheImpl = new ProfileCache(factory.createCacheFromDB());
        MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
        ObjectName profileCache = new ObjectName("org.javalobby.tnt.jmx:type=ProfileCacheInterfaceMBean");  
        mbs.registerMBean(cacheImpl, profileCache);

However i keep getting the below exception and I am not sure what I need to change

javax.management.NotCompliantMBeanException: MBean class com.vimba.cache.ProfileCache does not implement DynamicMBean, and neither follows the Standard MBean conventions (javax.management.NotCompliantMBeanException: Class com.vimba.cache.ProfileCache is not a JMX compliant Standard MBean) nor the MXBean conventions (javax.management.NotCompliantMBeanException: com.vimba.cache.ProfileCache: Class com.vimba.cache.ProfileCache is not a JMX compliant MXBean)

I think potentially it's because it returns a Map?

Answer

Bjorn Sayers picture Bjorn Sayers · May 8, 2015

Having just encountered this exception and looked at the current answers as well as https://blogs.oracle.com/jmxetc/entry/javax_management_standardmbean_when_and I thought it might help to emphasize and clarify the following already elucidated to:

  1. The NotCompliantMBeanException is caused, among other things, by failing to follow this convention 'ConcreteClassName' implements 'ConcreteClassNameMBean'

  2. I resolved this by updating the original name of my mbean interface from 'OrignalNameMBean' to 'OriginalNameMXBean' allowing the mbean to be registered without following the convention

  3. Another solution would be to follow the convention.