I am currently working on http://truevfs.java.net , a virtual file system for Java. TrueVFS is modular and uses a plug-in architecture to load features at run-time without the need for configuring anything. Some optional plug-ins use the platform MBeanServer to register MBeans with defined ObjectNames for monitoring and management.
Now some of my users are bundling the TrueVFS JARs in their WAR for deployment to Tomcat et al. This is working fine unless they include one of the JMX enabled plug-ins and deploy several instances of the WAR at different contexts.
This doesn't work because each web app has its own class loader definition of the JMX enabled plug-in, but they will all share the same platform MBeanServer and use the same ObjectNames to register their MBeans, so there is a collision.
Now how can I solve this problem? I have already abstracted the MBeanServer lookup so that I could extract it into another plug-in, but I can't identify a generally applicable strategy which MBeanServer I should use to register my MBeans.
I googled the subject and found some documentation for WebLogic which indicates that I should look up the MBeanServer using JNDI. However, this seems to be specific to WebLogic.
Isn't there a general one-size-fits-all approach?
Update:
Here's a quick proof-of-concept for using an additional property to identify the web app defined class loader:
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(); }
As expected, this program registers two Messenger MBeans, finds them and prints their "Hello world!" message.
However, there are disadvantages to this solution:
These are serious constraints, but it seems I have no better option, so I will probably go this way.
In netbeans default web server is glassfish but i recommended to use tomcat as in many company we develop web application using only tomcat. , I'm a java developer, who loves to code. It depends on your use case. First of all, it is important to know the difference between glassfish and tomcat.
Oracle Weblogic Server is a fully loaded container with EJB support, whereas Apache Tomcat Server is a Servlet and JSP support container.
GlassFish vs Tomcat – Apache Tomcat? On the the hand, Tomcat is a web container (a.k.a servlet container) and HTTP server. As a servlet container, it’s a component of the web server that interacts with Java Servlets and implements the Servlets and JSP specification. Likewise it’s open source and maintained by the Apache Software Foundation.
Oracle Weblogic Server has a broader approval, being mentioned in 9company stacks & 14developers stacks; compared to GlassFish, which is listed in 5company stacks and 4developer stacks. Get Advice from developers at your company using Private StackShare.
You could create a new MBeanServer afresh for each war module. However, when querying them from the outside a JSR-160 client you need to specify the MBeanServer as well.
When you are using Jolokia you get a transparent merging of all MBeanServers of the JVM. However, this won't help here either when you have MBeans with identical names where only one will be reachable.
My solution for this situation is to use the same MBeanServer but MBeans with different names. You could use completely orthogonal domains for those MBeans or add something like an extra "qualifier" key-value pair in the name in addition to the other properties. When I expect only one MBean for typical situations, then I first try to add the MBean with a fixed name. If this fails, I add another ",qualifier=..."
part to the name with either an automatically generated value, one which can be uniquely identified by some value (like the WAR name) or even a configurable one.
In fact, dealing with multiple MBeanServers is really a pain from the clients perspective so using JMX as global namespace with unique (maybe partially generated MBean names) is the simple option.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With