用Java创建MBean

问题描述 投票:12回答:8

我正在尝试使类实现MBean接口,以便我可以在运行时询问属性。我试图询问的课程如下

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;
    }


}

界面看起来像这样

import com.vimba.profile.Profile;

public interface ProfileCacheInterfaceMBean {

    ConcurrentMap<String, Profile> getCache();

}

我就像这样开始MBean

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

但是我继续得到以下异常,我不确定我需要改变什么

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)

我认为可能是因为它返回了一张地图?

java jmx mbeans
8个回答
22
投票

刚刚遇到这个例外并查看了当前的答案以及https://blogs.oracle.com/jmxetc/entry/javax_management_standardmbean_when_and我认为可能有助于强调和阐明以下内容已经阐明:

  1. NotCompliantMBeanException是由于未能遵循此约定而引起的'ConcreteClassName'实现'ConcreteClassNameMBean'
  2. 我通过将我的mbean接口的原始名称从'OrignalNameMBean'更新为'OriginalNameMXBean'来解决这个问题,从而允许在不遵循约定的情况下注册mbean
  3. 另一种解决方案是遵循惯例。

8
投票

我遇到了同样的问题(“没有实现DynamicMBean,也没有遵循标准MBean约定”),本文帮助我解决了这个问题(请参阅使用StandardMBean部分:https://blogs.oracle.com/jmxetc/entry/javax_management_standardmbean_when_and)。

我必须明确地构建一个

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

然后注册mbean:

mbServer.registerMBean(mbean, mBeanName);

有用。

当我使用mbServer注册mBeanImpl时,我得到了上述异常。


6
投票

实现mbean类可以声明许多未在mbeans接口中定义的方法...不要求实现类只能/必须实现接口方法。

在许多情况下,这个问题是由于mbean接口和实现类不在同一个包中引起的!


2
投票

您可以将接口名称从SomethingMBean更改为SomethingMXBean,例如将HelloMBean更改为HelloMXBean,从jdk的源代码我看到:

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");
}

如果没有结束使用“MXBean”,它将返回false,然后导致抛出IllegalArgumentException

jdk版本:1.8.0_25

class是“JMX”,第376行


1
投票

只需将您的实现类名称从ProfileCache更改为ProfileCacheInterface。它现在应该工作。此外,您的实现类可以拥有任意数量的自己的方法,并且MBean接口中不需要提及这些方法。

JMX的标准mbean命名约定是这样的

    public interface SomeBeanNameMBean{
    ...
    }

    public class SomeBeanName implements SomeBeanNameMBean{
    ...
    //implements all the methods of SomeBeanNameMBean
    ...
    //implement other class's own methods if needed
    }

0
投票

我遇到了同样的问题,如'线程中的异常'主“javax.management.NotCompliantMBeanException”,在我的情况下,我在varynet包中保留了MBean接口和实现类。为了解决这个问题,我将MBean接口和实现类都移到了同一个包中。


0
投票

在我为MBean实现看到的所有示例中,我从未见过类定义了一个未在接口中定义的方法。例如,ProfileCache有方法updateCache,但ProfileCacheInterfaceMBean没有。尝试从ProfileCache中删除updateCache方法,看看它是否可行。


0
投票

只需将接口后缀从“MBean”更改为“MXBean”即可。这适合我。

© www.soinside.com 2019 - 2024. All rights reserved.