実行時にプロパティを調べることができるように、クラスに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 すでに解明されている次のことを強調し、明確にするのに役立つかもしれないと思いました。 :
NotCompliantMBeanExceptionは、特に、この規則に従わなかったことが原因で発生します。「ConcreteClassName」は「ConcreteClassNameMBean」を実装します。
これを解決するには、mbeanインターフェイスの元の名前を「OrignalNameMBean」から「OriginalNameMXBean」に更新して、規則に従わずにmbeanを登録できるようにしました。
別の解決策は、規則に従うことです。
同じ問題が発生し(「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);
できます。
MBeanImplをmbServerに登録すると、上記の例外が発生しました。
実装するmbeanクラスは、mbeansインターフェイスで定義されていないメソッドを好きなだけ宣言できます...実装クラスがインターフェイスメソッドを実装できる/しなければならないという要件はありませんのみ。
多くの場合、この問題はmbeanインターフェースと実装クラスが同じパッケージにない!が原因で発生します。
インターフェイス名を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");
}
終了しない場合「MXBean」を使用すると、falseが返され、IllegalArgumentExceptionがスローされます。
jdkバージョン:1.8.0_25
クラスは「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の例外」のような同じ問題に直面しました。私の場合、MBeanインターフェースと実装クラスをdiffernetパッケージに保持しました。この問題を解決するために、MBeanインターフェースと実装クラスの両方を同じパッケージに移動しました。
MBeanの実装について見たすべての例で、インターフェイスで定義されていないメソッドをクラスが定義するのを見たことがありません。たとえば、ProfileCacheにはメソッドupdateCacheがありますが、ProfileCacheInterfaceMBeanにはありません。 ProfileCacheからupdateCacheメソッドを削除して、機能するかどうかを確認してください。
インターフェイスのサフィックスを「MBean」から「MXBean」に変更するだけです。これは私にとってはうまくいきます。