我正在尝试使类实现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)
我认为可能是因为它会返回一张地图?
答案 0 :(得分:21)
刚刚遇到这个例外并查看了当前的答案以及https://blogs.oracle.com/jmxetc/entry/javax_management_standardmbean_when_and我认为可能有助于强调和澄清已经阐明的以下内容:
NotCompliantMBeanException是由于未能遵循此约定而导致的。&#39; ConcreteClassName&#39;实现&#39; ConcreteClassNameMBean&#39;
我通过从&#39; OrignalNameMBean&#39;更新我的mbean接口的原始名称来解决这个问题。 to&#39; OriginalNameMXBean&#39;允许mbean在不遵循惯例的情况下进行注册
另一种解决方案是遵循惯例。
答案 1 :(得分:8)
我遇到了同样的问题(&#34;没有实现DynamicMBean,也没有遵循标准MBean约定&#34;)本文帮助我解决了这个问题(请参阅使用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时,我得到了上述异常。
答案 2 :(得分:6)
实现mbean类可以声明许多未在mbeans接口中定义的方法...不要求实现类可以/必须仅实现接口方法。 / p>
在许多情况下,导致此问题的原因是 mbean接口和实现类不在同一个包中!
答案 3 :(得分:2)
您可以将界面名称从SomethingMBean更改为SomethingM X Bean,例如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");
}
如果没有结束&#34; MXBean&#34;,它将返回false,然后导致抛出IllegalArgumentException
jdk版本:1.8.0_25
类是&#34; JMX&#34;,第376行
答案 4 :(得分: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
}
答案 5 :(得分:0)
在我为MBean实现看到的所有示例中,我从未见过类定义了一个未在接口中定义的方法。例如,ProfileCache有方法updateCache,但ProfileCacheInterfaceMBean没有。尝试从ProfileCache中删除updateCache方法,看看它是否可行。
答案 6 :(得分:0)
我遇到了同样的问题,例如“线程“ main”中的异常javax.management.NotCompliantMBeanException”,在我的情况下,我将MBean接口和实现类保留在differentnet包中。为了解决此问题,我将MBean接口和实现类都移到了同一程序包中。
答案 7 :(得分:0)
只需将接口后缀从“ MBean”更改为“ MXBean”。 这对我有用。