我目前正在研究http://truevfs.java.net,一个用于Java的虚拟文件系统。 TrueVFS是模块化的,使用插件架构在运行时加载功能,而无需进行任何配置。一些可选插件使用平台MBeanServer来注册具有已定义ObjectNames的MBean以进行监视和管理。
现在我的一些用户正在将WARV中的TrueVFS JAR捆绑到Tomcat等人。除非它们包含一个启用JMX的插件并在不同的上下文中部署WAR的几个实例,否则这样可以正常工作。
这不起作用,因为每个Web应用程序都有自己的JMX启用插件的类加载器定义,但它们都将共享相同的平台MBeanServer并使用相同的ObjectNames来注册它们的MBean,所以有碰撞。
现在我该如何解决这个问题?我已经抽象了MBeanServer查找,以便我可以将它提取到另一个插件中,但我无法确定一个通常适用的策略,MBeanServer我应该使用它来注册我的MBean。
我搜索了主题并发现了一些documentation for WebLogic,表明我应该使用JNDI查找MBeanServer。但是,这似乎是WebLogic特有的。
不是一般的“一刀切”方法吗?
更新
这里是使用附加属性识别Web应用程序定义的类加载器的快速概念验证:
import java.lang.management.ManagementFactory;
import javax.management.JMX;
import javax.management.MBeanServer;
import javax.management.ObjectName;
public class Messenger implements MessengerMXBean {
private static MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
public static void main(String[] args ) throws Exception {
register("one");
register("two");
find();
System.out.println("Waiting for interrupt...");
Thread.sleep(Long.MAX_VALUE);
}
private static void register(String context) throws Exception {
mbs.registerMBean(new Messenger(),
new ObjectName(":type=Messenger,context=" + context));
}
private static void find() throws Exception {
for (ObjectName name : mbs.queryNames(new ObjectName(":type=Messenger,*"), null))
System.out.println(JMX.newMXBeanProxy(mbs, name, MessengerMXBean.class).getMessage());
}
public String getMessage() { return "Hello world!"; }
}
public interface MessengerMXBean { String getMessage(); }
正如预期的那样,这个程序注册了两个Messenger MBean,找到它们并打印出他们的“Hello world!”#34;消息。
但是,此解决方案存在缺点:
这些是严重的限制,但似乎我没有更好的选择,所以我可能会这样做。
答案 0 :(得分:4)
您可以为每个war模块重新创建一个新的MBeanServer。但是,当从外部查询JSR-160客户端时,您还需要指定MBeanServer。
当您使用Jolokia时,您将获得JVM的所有MBeanServers的透明合并。但是,当你拥有相同名称的MBean,只有一个可以访问时,这在这里不会有帮助。
我遇到这种情况的解决方案是使用相同的MBeanServer,但使用具有不同名称的MBean。您可以为这些MBean使用完全正交的域,或者添加类似额外的"限定符"除了其他属性之外,名称中的键值对。当我期望只有一个MBean用于典型情况时,我首先尝试添加具有固定名称的MBean。如果失败,我会在名称中添加另一个",qualifier=..."
部分,其中包含一个自动生成的值,一个可以通过某个值(如WAR名称)唯一标识的值,或者甚至是可配置的值。
事实上,从客户角度来看,处理多个MBeanServers确实很痛苦,因此使用JMX作为具有唯一(可能是部分生成的MBean名称)的全局命名空间是一个简单的选项。