【问题标题】:Creating MBean in Java在 Java 中创建 MBean
【发布时间】:2014-08-14 13:04:20
【问题描述】:

我正在尝试让一个类实现一个 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)

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

【问题讨论】:

  • 感谢您提供如此有用的评论,如果我明白我的意思,我就不会在这里发布。毫无疑问,您的讽刺应该可以帮助您获得更多分数 - 干得好
  • 这是一个真正的问题。无论如何,您不了解异常的哪一部分?一开始,用“不实现” --> 表示你的类需要实现接口。
  • 这是我困惑的根源,因为我遵循的教程没有实现这个接口 - 也许我应该去 rtfm
  • 将托管 Bean 类名重命名为“YourClasssNameMXBean”对我有用。

标签: java jmx mbeans


【解决方案1】:

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

  1. NotCompliantMBeanException 的原因之一是未遵循此约定“ConcreteClassName”实现“ConcreteClassNameMBean”

  2. 我通过将 mbean 接口的原始名称从“OrignalNameMBean”更新为“OriginalNameMXBean”来解决此问题,从而允许在不遵循约定的情况下注册 mbean

  3. 另一种解决方案是遵循约定。

【讨论】:

  • 链接失效
  • 但是解决方案仍然有效:)
【解决方案2】:

我遇到了同样的问题(“没有实现 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 时,出现上述异常。

【讨论】:

  • 对我来说最好的答案
【解决方案3】:

实现的 mbean 类可以声明任意数量的未在 mbeans 接口中定义的方法...不要求实现类可以/必须实现接口方法。

在很多情况下,这个问题是因为mbean接口和实现类不在同一个包中

【讨论】:

  • 确实是这样,谢谢!将接口移动到与实现相同的包中,为我解决了错误。
  • 我遇到了同样的问题,因为接口和实现在同一个耳朵的不同工件中,并且有一个重构没有考虑 api 工件中的包结构。将实现工件中的包结构解析为与api工件相同后,错误消失了。
【解决方案4】:

你可以将接口名称从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

类是“JMX”,第 376 行

【讨论】:

    【解决方案5】:

    只需将接口后缀从“MBean”更改为“MXBean”。 这对我有用。

    【讨论】:

      【解决方案6】:

      只需将您的实现类名称从 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
          }
      

      【讨论】:

        【解决方案7】:

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

        【讨论】:

          【解决方案8】:

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

          【讨论】:

          • 两者都有getCache方法?
          • 只需尝试注释掉 ProfileCache 中的 updateCache 方法,看看是否仍然抛出该异常。
          • 为什么会有任何不同?!
          • 因为看起来 MBean 实现要求只实现接口方法; ProfileCache 中不应实现其他方法。此时,如果您在尝试评论 updateCache 之前发表另一条评论,您就是在拖钓代表。
          • 下面的答案是正确的。在 MBean 实现中添加额外的方法是没有问题的
          猜你喜欢
          • 1970-01-01
          • 2013-08-05
          • 2010-10-14
          • 1970-01-01
          • 1970-01-01
          • 2015-12-04
          • 2021-08-12
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多