> Inside the servlet I print out
> "MBeanServerFactory.findMBeanServer(null).size()" and
> I get 0. Any ideas?
It *may* be that you load the jmx classes with 2 different classloaders, so that also static variables are duplicated.
> Also, the AgentID parameter that the findMBeanServer
> method takes...what is that? I've tried putting in
> the Bean Domain name, full objectname, everything,
> and nothing seems to work. What should I pass here to
> get the specific MBeanServer for my MBean?
It takes the agent id, which is not defined by the spec (every implementation can decide to create its own format). However you can get the agent id from the MBeanServerDelegate MBean, that is always present in a JMX Agent. But if you know the MBeanServer on which invoke the MBeanServerDelegate, then you already have it.
So, go figure out what happened here ]:)
> I know I had this working before, but now it seems to
> have disappeared. Where have all my MBeanServers gone
> and why can't I see them from my servlet? Could it be
> because the servlet is auto-deployed in JBoss instead
> of pre-setup in Catalina?
As I told it may be a classloader problem.
I am working with Andrew on this. What I have run into is this. I have a servlet which simply calls "MBeanServerFactory.findMBeanServer(null)", and then displays the number of servers found. Last night it ran fine over and over, returning a value of "5". Suddenly, with no code changes, it started returning "0". Why would it change?
As Simone says, the description is consistent with a classloader problem.
Is your servlet using the same classloader (or a child of) the same classloader that loaded the JMX implementation?
If you can reproduce the problem between restarts of the VM then try this:
Have one of your MBeans println MBeanServerFactory.class.getClassLoader()
and then have your servlet do exactly the same thing.
I'm 99% confident it will be two different loaders...
Hi Trevor and Simone,
Thanks very much for your replies. Trevor's suggestion proved both of your guesses right, they are using different class loaders. The MBean Service is using "sun.misc.Launcher$AppClassLoader@71732b" while the servlet is using "java.net.FactoryURLClassLoader@7cd37a".
However I still have the dilemma of how to be able to find my MBean from my servlet. Is it even possible? My understanding of MBeanServerFactory.findMBeanServer was that it would find all MBeanServers in the current JVM. Is this not the case?
Do either of you have a suggestion as to how to solve this problem? Both servlet and MBean are running in the same instance of JBoss (only one java.exe is running, this has been confirmed). Shouldn't the servlet be able to find MBeans that were started by something other than another servlet?
Thanks for any suggestions,
Ok we've sorta solved it by using the RMIClientConnectorImpl class to get the MBeanServer instead of MBeanServerFactory. I guess this is better since then the servlet doesn't have to be in the same JVM as the MBean. But if anyone can shed light on what went wrong, or provide an alternative solution, my curiosity has been peaked so let's hear it.
good to know you've got a solution... and that you've somehow managed to turn a bugette into a feature - nice one.
It all boils down to what was seen with the different classloaders for MBeanServerFactory.
Forgive me if I start saying things you already know.
If you can imagine that MBeanServerFactory holds a static ArrayList (for example) of MBeanServers. I'm not sure if the detail is right but I like to think of statics as being instance members of a class instance.
I.e. the only way you can have two different static lists of MBeanServers being maintained by something that thinks it's an MBeanServerFactory is if you have two instances of MBeanServerFactory.class.
The only way you can have that is if you have two different classloaders that load the MBeanServerFactory bytecode.
Now if we assume that these two classloaders involved playing by the accepted delegation rules, their common delegation parent(s) have *not* loaded the MBeanServerFactory bytecode.
If a delegation parent *had* loaded the bytecode then there would one MBeanServerFactory.class shared by the two classloaders I have been yammering on about.
So, to overcome the problem you are encountering you must move the offending classes higher in the classloader delegation chain.
I.e. you could try moving the JMX implementation jar into the system classpath.
To be honest though, my first port of call would be to move this question onto either the installation/configuration forum or the http/servlets forum because you may be making a common mistake (common to catalina integration that is). Moving the JMX impl into the sysetm classpath may break more than it fixes - I really don't know.
I hope this helps.
I tried this with JBoss2.4.4-Tomcat4 last night.
My servlet got the same classloader as the Service MBean.
In JBoss, jmxri.jar is loaded using a manifest entry
in run.jar, so it is part of the system classloader.
This gets checked first when loading classes.
Perhaps you can produce a simple testcase that has your
problem? I'll debug it and try to locate the problem.
Ok guys I moved a few jars from the MBean war to the JBoss lib/ext directory and all is well. Many thanks for your help, much appreciated.