4

我在 WebLogic 服务器上部署了几个应用程序。这些应用程序公开了一些 JMX MBean。当我通过 JConsole 或 JRMC 远程调用这些 MBean 上的操作时,它们工作正常。

但由于 JMX 对防火墙并不友好,我创建了另一个简单的 Servlet 应用程序,它部署在同一台服务器上,并调用一组本地 MBean 上的操作。在 servlet 中,我使用 ManagementFactory.getPlatformMBeanServer() 来查找和调用部署在同一 JVM 中的其他应用程序的 MBean,但对于某些操作,我得到 ClassCastException 或 ClassNotFoundException,具体取决于调用的操作,但某些操作可以正常工作。

有任何想法吗?

4

1 回答 1

3

我怀疑这里发生的事情是您的 servlet 线程具有与您正在调用的 MBean 不同的上下文类加载器。因此,如果 MBean 属性、操作参数或返回值包含的类型不是核心 JVM 类(或未从同一个根类加载器共享的类),您将获得 ClassCast、ClassNotFound 和 ClassDefNotFound 异常。

此过程可能对您有用。您需要做的是临时将 servlet 线程的上下文类加载器更改为与加载 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 回答