0

MBeanパラメータとしてaを使用することに問題がMap<String, Object>あります。プロキシオブジェクトを使用してJMX経由で実行しようとすると、例外が発生します。

Caused by: javax.management.ReflectionException
    at org.jboss.mx.server.AbstractMBeanInvoker.invoke(AbstractMBeanInvoker.java:231)
    at org.jboss.mx.server.MBeanServerImpl.invoke(MBeanServerImpl.java:668)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
Caused by: java.lang.IllegalArgumentException: Unable to find operation updateProperties(java.util.HashMap)

インターフェイスではなく実際の実装クラスを使用しようとしているようで、これが必要なインターフェイスの子であるかどうかはチェックされません。同じことが拡張クラスでも発生します(たとえば、declare HashMap、pass in LinkedHashMap)。これは、そのようなメソッドにインターフェイスを使用することが不可能であることを意味しますか?現時点では、メソッドのシグネチャを変更してを受け入れるようHashMapにしていますが、でインターフェイス(または拡張クラス)を使用できないのは奇妙に思えますMBeans

編集:プロキシオブジェクトは、と呼ばれる社内ユーティリティクラスによって作成されていますJmxInvocationHandler。それの(うまくいけば)関連する部分は次のとおりです:

public class JmxInvocationHandler implements InvocationHandler
{
    ...
    public static <T> T createMBean(final Class<T> iface, SFSTestProperties properties, String mbean, int shHostID)
    {
        T newProxyInstance = (T) Proxy.newProxyInstance(iface.getClassLoader(), new Class[] { iface }, (InvocationHandler) new JmxInvocationHandler(properties, mbean, shHostID));
        return newProxyInstance;
    }
    ...
    private JmxInvocationHandler(SFSTestProperties properties, String mbean, int shHostID)
    {
        this.mbeanName = mbean + MBEAN_SUFFIX + shHostID;
        msConfig = new MsConfiguration(properties.getHost(0), properties.getMSAdminPort(), properties.getMSUser(), properties.getMSPassword());
    }
    ...
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
    {
        if (management == null)
        {
            management = ManagementClientStore.getInstance().getManagementClient(msConfig.getHost(),
                    msConfig.getAdminPort(), msConfig.getUser(), msConfig.getPassword(), false);
        }

        final Object result =  management.methodCall(mbeanName, method.getName(), args ==  null?  new Object[] {} : args);
        return result;
    }
}
4

1 に答える 1

2

とった。JMXの呼び出しにより、目的のユーティリティクラスの大砲の飼料が作成されることがあります.... :)

この男は、私が思うに、問題です:

public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
    {
        if (management == null)
        {
            management = ManagementClientStore.getInstance().getManagementClient(msConfig.getHost(),
                    msConfig.getAdminPort(), msConfig.getUser(), msConfig.getPassword(), false);
        }

        final Object result =  management.methodCall(mbeanName, method.getName(), args ==  null?  new Object[] {} : args);
        return result;
    }

これは、MBeanの操作シグネチャ(継承については気にしない)が、渡された引数のクラスから決定されるためです。getClass()を返す実際の具象オブジェクトを渡すことはできないためjava.util.Map、引数自体の直接型を使用して一致させることはできません。(同じ理由でプリミティブでも同様の問題が発生します)。

この問題(またはあなたが抱えていると思う問題)をもう少し詳しく説明しているので、「MetaMBeanを作成する際のトリッキーな部分の1つ」で始まる段落から始まるこのブログ投稿を参照してください。ただし、 MBeanServerのinvokeメソッド[接続]は:

invoke(ObjectName name, String operationName, Object[] params, String[] signature) 

最初の2つと最後の引数は、サーバーで公開されているすべての操作の中でどの操作を呼び出すかを正確に指定するという点でナビゲーションです。この問題を回避する最善の方法は、署名を「推測」する必要がなく、ObjectNameと操作名のみに依存することです。これは、ターゲットMBeanのMBeanInfoMBeanOperationInfoに問い合わせる(場合によってはキャッシュする)ことで実行できます。 。MBeanOperationInfosは署名を提供するため、推測する必要はありません。

これが本当にあなたの問題である場合、あなたがそれに対処することができるいくつかの方法があります:

  1. MBeanの操作名が一意である場合(つまり、オーバーロードがない場合)、op名を使用してMBeanInfoを取得できます。
  2. MBeanの操作がオーバーロードされている場合(つまり、同じ名前でパラメーターが異なる複数の操作がある場合)...ただし、それらすべてのパラメーター数が異なる場合は、MBeanOperationInfosで一致するすべての操作名を繰り返すことにより、正しい署名を簡単に判別できます。パラメータカウントによるマッチング。
  3. #1と#2が当てはまらない場合は、注意が必要です。MBeanのコードのメソッドシグネチャを再評価します。
  4. #1と#2が適用されず、#3が準拠しない場合は、MetaMBeanと呼ばれるGmxのこのクラスを確認ください。最新のリビジョンでは、Groovyを使用して、MBeanのMBeanInfoを使用してコンパイル済みのランタイムインターフェイスを作成し、メソッド呼び出しで継承(および自動ボクシング)を機能させます。同じメソッドをJavaScript(Java 6以降に組み込まれているという利点があります)または他のいくつかのJVMスクリプト言語で実装できます。または、既知の操作シグネチャに対してパターンマッチングを試み た以前のバージョンを見てください(実際にはかなりうまく機能しましたが、とにかくGroovyを使用していたので......)

これがお役に立てば幸いです。これが根本的な原因ではないことが判明した場合は、私が何かを言ったことを忘れてください。

于 2012-07-02T19:38:27.877 に答える