我在 WebLogic 服务器上部署了几个应用程序。这些应用程序公开了一些 JMX MBean。当我通过 JConsole 或 JRMC 远程调用对这些 MBean 的操作时,它们工作正常。
但由于 JMX 并不是真正的防火墙友好型,我创建了另一个简单的 Servlet 应用程序,该应用程序部署在同一台服务器上,并在一组本地 MBean 上调用操作。在 servlet 中,我使用 ManagementFactory.getPlatformMBeanServer() 来查找和调用部署在同一 JVM 中的其他应用程序的 MBean,但对于某些操作,根据调用的操作,我得到 ClassCastException 或 ClassNotFoundException,但某些操作工作正常。
有任何想法吗?
最佳答案
我怀疑这里发生的事情是您的 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);
}
}
关于weblogic - 远程调用 JMX MBean 或从部署在同一 JVM 中的 servlet 的差异,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10532859/