我在WebLogic服务器上部署了多个应用程序。这些应用程序公开了一些JMX MBean。当我通过JConsole或JRMC远程调用这些MBean上的操作时,它们工作正常。
但是由于JMX实际上不是防火墙友好的,我创建了另一个简单的Servlet应用程序,该应用程序部署在同一台服务器上并调用集合本地MBean上的操作。在servlet中,我使用ManagementFactory.getPlatformMBeanServer()来查找和调用部署在同一JVM中的其他应用程序的MBean,但是对于某些操作,我得到ClassCastException或ClassNotFoundException,具体取决于所调用的操作,但有些操作可以正常工作。 p>
有什么想法吗?
答案 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);
}
}