4

WebLogicサーバーにいくつかのアプリケーションをデプロイしています。これらのアプリケーションは、いくつかのJMXMBeanを公開します。これらのMBeanの操作をJConsoleまたはJRMCを介してリモートで呼び出すと、正常に機能します。

しかし、JMXは実際にはファイアウォールに対応していないため、同じサーバーにデプロイされ、設定されたローカルMBeanで操作を呼び出す別の単純なサーブレットアプリケーションを作成しました。サーブレット内から、ManagementFactory.getPlatformMBeanServer()を使用して、同じJVMにデプロイされた他のアプリケーションのMBeanを検索して呼び出しますが、一部の操作では、呼び出される操作に応じてClassCastExceptionまたはClassNotFoundExceptionが発生しますが、一部の操作は正常に機能します。

何か案は?

4

1 に答える 1

3

ここで起こっていることは、サーブレットスレッドに、呼び出しているMBeanのコンテキストクラスローダーとは異なるコンテキストクラスローダーがあることだと思います。したがって、MBean属性、操作パラメーター、または戻り値にコアJVMクラスではないタイプ(または同じルートクラスローダーから共有されていないクラス)が含まれている場合、ClassCast、ClassNotFound、およびClassDefNotFound例外が発生します。

この手順はあなたのために働くかもしれません。必要なのは、サーブレットスレッドのコンテキストクラスローダーを、MBeanがロードされたのと同じクラスローダーに一時的に変更することです。呼び出しが完了したら、再度設定します。ターゲットMBeanのObjectNameがわかっているので、MBeanServerは正しいクラスローダーを提供します。

基本的な例は次のとおりです。

public void callMBean() throws MalformedObjectNameException, NullPointerException, InstanceNotFoundException {
    final ClassLoader currentClassLoader = Thread.currentThread().getContextClassLoader();
    try {
        ObjectName targetObjectName = new ObjectName(".....");
        MBeanServer server = ManagementFactory.getPlatformMBeanServer();
        ClassLoader tmpClassLoader = server.getClassLoaderFor(targetObjectName);
        Thread.currentThread().setContextClassLoader(tmpClassLoader);
        // ==========================================
        // Invoke operations here
        // ==========================================
    } finally {
        Thread.currentThread().setContextClassLoader(currentClassLoader);
    }
}
于 2012-05-10T11:58:52.113 に答える