The Mystery Of Multiple MBeanServers

JConsole and VisualVM have made it very simple to access MBeans in a remote target VM. There's also a lot of blogs and documents that explain how to access remote MBeans programmatically.

But how do you access local MBeans registered in your own JVM?

To access local MBeans registered in a local MBeanServer in your own JVM you need a direct reference to that MBeanServer.

A JVM can contain any number of MBeanServers, which are usually created by the MBeanServerFactory . If an MBeanServer was created using one of the MBeanServerFactory.createMBeanServer() method it can be later retrieved using MBeanServerFactory.findMBeanServer().

Some other MBeanServers might have been been created using one of the MBeanServerFactory.newMBeanServer() and in that case, the only way to get a reference of those is to obtain it from the code that created them.

Among all the MBeanServers living in a JVM, there is a special one, called the platform MBeanServer. This is the MBeanServer to which JConsole and VisualVM connect when they attach to a local process. The special thing about the platform MBeanServer is that it contains all the platform MBeans defined by the java.lang.management API. It is also the only MBeanServer which can be exposed using the out-of-the-box JMX agent.
If you want to expose another MBeanServer to a remote application, you will need to create and start your own JMXConnectorServer to expose it.

Usually, a JVM will contain a single MBeanServer, and this will be the platform MBeanServer. If you want to add your own MBeans to that MBeanServer it is very simple: you can get a direct reference to the platform MBeanServer of your JVM by calling ManagementFactory.getPlatformMBeanServer(). If you register your own MBeans in the platform MBeanServer of your JVM, they will become automatically visible to applications like JConsole and VisualVM which connect to that MBeanServer.

Some applications however may use and expose more than one MBeanServer. If you use a direct JMXServiceURL to connect to such an application with JConsole or VisualVM, you might get connected to that other MBeanServer. If you don't see any of the java.lang.management API MXBeans or if some (or all) of the usual tabs are unavailable, it's probably because you are connecting to another MBeanServer than the platform MBeanServer.

Hope this helps!

-- daniel

Comments:

Hey Daniel,

I'm getting

Getting "Invalid character '\*' in value part of property"

for a JMX wild card query using the URL

"org.jruby:type=Runtime,name=\*,service=\*". This is using JDK 6. Any idea what is wrong ?

I could not find any good examples as well.

-Arun

Posted by Arun Gupta on January 07, 2009 at 12:05 AM CET #

Hi Daniel,

I have an application server running on jboss, and a client application in standalone, the client application has its mbean (named callback) which I register using the way you described:
MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
mbs.registerMBean(callBack, ObjectName.getInstance(callbackMBeanName));

My server get the reference of this mbean via a request from the client and it should be able to access it (access the mbean) but it can not, I got this exception:
Caused by: javax.management.InstanceNotFoundException: com.\*\*\*.\*\*\*.\*\*\*.pl:type=callback,applicationName=\*\*\*\*\*,name=6f68a844-bbab-43a9-9882-790792cb0797,version=2.1 is not registered.

In the same time I can access and monitor this mbean via jconsole!!!

Can you please help me how to access this mbean from my server app?

Regards

Posted by Abdelmonam on June 08, 2009 at 05:09 AM CEST #

Hi,

As far as I understand you register your MBean in your Client JVM and expect your application in the Server JVM to see it. This is a bit weird.

You should probably instead create your MBean on the server side - or as an alternative, start a JMXConnectorServer on the client side and pass its address to the server - but this does not sound right.

best regards,

-- daniel

Posted by daniel on June 09, 2009 at 04:16 AM CEST #

Hi,

In fact my server has its own mbeans and I can access them via client without problem. The problem is that my client should create an callback mbean (my own callcack in which I implement my specific methods) and register it on its side, then send its mbeanName to the server in a request and then the server execute some operations and return results to client via this callback mbean.

My problem is that I can not locate the mbeanServer resulting of this line:
MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();

and in which I registred my callback mbean.

Regards

Posted by Abdelmonam Kouka on June 09, 2009 at 11:20 AM CEST #

There is one Platform MBeanServer per JVM. You have two JVMs: the client JVM and the server JVM - so you have two Platform MBeanServers.

You should consider creating your MBean on the server side (not on the client side as you do now) - and have it emit a notification when the job is completed.

-- daniel

Posted by daniel on June 09, 2009 at 11:43 AM CEST #

Found this via Google. It's nice to see a simple summary in simple language.

I have an app which registers an MBean with the Platform MBeanServer (after which it blocks). On the same machine, I have another app which prints the Set<ObjectName> returned from platformServer.queryNames().

Strangely, the set printed by the second app does not list contain the custom MBean registered by the first app. Why is that? I mean, there's only one Platform MBeanServer, so both apps should be looking at the same one, right?

If I copy/paste the code from the second app into the first app, I \*do\* see the MBean.

Can you clarify how this can be?

Thanks
-Grant

Posted by Grant Birchmeier on September 22, 2009 at 03:10 PM CEST #

Hi Grant,

There's one Platform MBeanServer \*per JVM\* - so if you have registered your MBean in the platform MBeanServer of the JVM of App1 and look for it in the Platform MBeanServer of the JVM of App2 you will not find it.

What you should do is make App1 register its MBean in its own platform MBeanServer (I guess that's what you already do) - and then make App2 connect to App1 in order to access the MBeanServer of App1 (like JConsole does).

For that you can either: create and register a JMXConnectorServer in App1 - and give its JMXServiceURL to App2 (plenty of example in tutorial etc...) - or make App2 connect to App1 through the out of the box agent (just like JConsole does).
If both App1 and App2 run on the same machine you can even use the attach API to make App2 connect to App1.

See http://blogs.sun.com/jmxetc/entry/how_to_retrieve_remote_jvm and http://blogs.sun.com/jmxetc/entry/a_small_program_that_prints

Hope this helps!

-- daniel

Posted by daniel on September 23, 2009 at 01:38 AM CEST #

Hi Daniel,

Hope you are doing good.
I have gone through the code of JVMRuntimeClient.java and its working fine when I pass the process id. But I want to find out the heap memory usage of the jboss application server which is running remotely. what should be the JMXServiceURL ?

Thanks,
Praveen

Posted by Praveen on October 09, 2009 at 06:23 AM CEST #

I am registering my MBean on the platform MBeanServer for WebSphere 6.1 however I do not see this MBean in the Set returned by queryNames(null,null) run in the same VM. Then when I attempt to re-register (same VM again), I get the InstanceAlreadyExistsException.

Elsewhere you have written that security can affect visibility of MBeans so I have ensured that the Java 2 Security is disabled in the WAS console and yet I still have this issue.

Is there some other requirements that I am not meeting?

Thanks you

Posted by goodaddy on October 27, 2009 at 12:06 PM CET #

Post a Comment:
  • HTML Syntax: NOT allowed
About

Daniel Fuchs blogs on Scene Builder, JMX, SNMP, Java, etc...

The views expressed on this blog are those of the author and do not necessarily reflect the views of Oracle.

Search

Categories
Archives
« April 2014
SunMonTueWedThuFriSat
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
Today