远程调用JMX MBean或从同一JVM中部署的servlet调用的差异

时间:2012-05-10 11:15:37

标签: weblogic jmx

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

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

有什么想法吗?

1 个答案:

答案 0 :(得分: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);
    }
}