我正在尝试使类实现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)
我认为可能是因为它返回了一张地图?
刚刚遇到这个例外并查看了当前的答案以及https://blogs.oracle.com/jmxetc/entry/javax_management_standardmbean_when_and我认为可能有助于强调和阐明以下内容已经阐明:
我遇到了同样的问题(“没有实现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时,我得到了上述异常。
实现mbean类可以声明许多未在mbeans接口中定义的方法...不要求实现类只能/必须实现接口方法。
在许多情况下,这个问题是由于mbean接口和实现类不在同一个包中引起的!
您可以将接口名称从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行
只需将您的实现类名称从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
}
我遇到了同样的问题,如'线程中的异常'主“javax.management.NotCompliantMBeanException”,在我的情况下,我在varynet包中保留了MBean接口和实现类。为了解决这个问题,我将MBean接口和实现类都移到了同一个包中。
在我为MBean实现看到的所有示例中,我从未见过类定义了一个未在接口中定义的方法。例如,ProfileCache有方法updateCache,但ProfileCacheInterfaceMBean没有。尝试从ProfileCache中删除updateCache方法,看看它是否可行。
只需将接口后缀从“MBean”更改为“MXBean”即可。这适合我。