Creating MBean in Java
Asked Answered
H

8

16

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?

Hexachlorophene answered 14/8, 2014 at 13:4 Comment(4)
Thanks for such a helpful comment, if i understood what was meant i would not have posted here. No doubt your sarcasm should help get you a few more points - good workHexachlorophene
That was a genuine question. Anyway, which part of the exception do you not understand? To start, with "does not implement" --> Indicates that your class needs to implement the interface.Unattended
This is the source of my confusion as the tutorial i followed did not implement this interface - maybe i should just go and rtfmHexachlorophene
Renaming the Managed Bean class name to end as "YourClasssNameMXBean" worked for me.Drillstock
M
35

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.

Marella answered 8/5, 2015 at 17:15 Comment(2)
The link is no longer validHaubergeon
But solution is still valid :)Interpleader
H
13

I had the same issue ("does not implement DynamicMBean, and neither follows the Standard MBean conventions") and this article helped me to resolve the problem (see Using StandardMBean section: https://blogs.oracle.com/jmxetc/entry/javax_management_standardmbean_when_and).

I have to explicitly construct a

StandardMBean mbean = new StandardMBean(mBeanImpl, MBeanInterface.class);

then register the mbean:

mbServer.registerMBean(mbean, mBeanName);

It works.

When I register the mBeanImpl with the mbServer, I got the above exception.

Hl answered 4/11, 2014 at 15:50 Comment(1)
best answer for mePeseta
N
8

The implementing mbean class can declare as many methods as it likes that are not defined in mbeans interface... There is no requirement that the implementing class can/must only implement the interface methods.

In many of the cases this problem is caused because the mbean interface and implementation class are not in the same package!

Nephritis answered 13/5, 2017 at 7:3 Comment(2)
This indeed was the case, thank you! Moving the interface into the same package as the implementation, resolved the error for me.Spermatic
I ran into the same issue because interface and implementation were in different artifacts of the same ear, and there was a refactor that did not account for the package structure in the api artifact. After resolving the package structure in the implementation artifact to be the same then the api artifact, the error disappeared.Schaffner
T
3

You can change interface name from SomethingMBean to SomethingMXBean,such as HelloMBean to HelloMXBean,from jdk's source code i saw this:

public static boolean isMXBeanInterface(Class<?> interfaceClass) {
    if (!interfaceClass.isInterface())
        return false;
    if (!Modifier.isPublic(interfaceClass.getModifiers()) &&
        !Introspector.ALLOW_NONPUBLIC_MBEAN) {
        return false;
    }
    MXBean a = interfaceClass.getAnnotation(MXBean.class);
    if (a != null)
        return a.value();
    return interfaceClass.getName().endsWith("MXBean");
}

if not endsWith "MXBean",it will return false,then cause throw IllegalArgumentException

jdk version:1.8.0_25

class is "JMX",line 376

Tolson answered 10/7, 2017 at 8:30 Comment(0)
E
2

Just change interface suffix from 'MBean' to 'MXBean'. This works for me.

Eagan answered 24/6, 2019 at 2:34 Comment(0)
R
1

Just change your implementation class name from ProfileCache to ProfileCacheInterface. It should work now. Moreover your implementation class can have any number of its own methods and those methods needs not to be mentioned in the MBean interface.

JMX's standard mbean naming convention is like this

    public interface SomeBeanNameMBean{
    ...
    }

    public class SomeBeanName implements SomeBeanNameMBean{
    ...
    //implements all the methods of SomeBeanNameMBean
    ...
    //implement other class's own methods if needed
    }
Roshan answered 26/1, 2015 at 2:57 Comment(0)
B
1

I faced the same problem like 'Exception in thread "main" javax.management.NotCompliantMBeanException', in my case I kept MBean interface and implementation classes in differnet package. To resolve the issue, I moved both MBean interface and the implementation class to same package.

Billington answered 24/7, 2018 at 4:49 Comment(0)
P
0

In the all the examples I've seen for MBean implementations, I've never seen a class define a method that was not defined in the interface. E.g., ProfileCache has method updateCache, but ProfileCacheInterfaceMBean does not. Try removing the updateCache method from ProfileCache and see if it will work.

Perspiratory answered 14/8, 2014 at 14:5 Comment(5)
both have the method getCache?Hexachlorophene
Just try commenting out method updateCache in ProfileCache and see if that exception is still thrown.Perspiratory
why would that make any difference though?!Hexachlorophene
Because it appears an MBean implementation requires that only the interface methods are implemented; no additional methods should be implemented in the ProfileCache. At this point, if you post another comment before trying to comment out updateCache, YOU'RE trolling for rep.Perspiratory
the answer below is the correct one. It is not a problem for adding additional methods in the MBean implementationHellenize

© 2022 - 2024 — McMap. All rights reserved.