Please note that this documentation is not final and is subject to change.

Java™ Platform
Standard Ed. 7

DRAFT ea-b76

Package javax.management.namespace

The javax.management.namespace package makes it possible to federate MBeanServers into a hierarchical name space.

See:
          Description

Interface Summary
Interface Description
JMXNamespaceMBean A JMXNamespace is an MBean that handles a name space in the MBeanServer hierarchical name space.
JMXRemoteNamespaceMBean A JMXNamespaceMBean that will connect to a remote MBeanServer by creating a JMXConnector from a JMXServiceURL.
 

Class Summary
Class Description
JMXDomain A special JMXNamespace that can handle part of the MBeanServer local name space.
JMXNamespace MBean Servers can be federated into a single hierarchical name space: A JMXNamespace is an MBean that handles a sub name space in that hierarchical name space.
JMXNamespacePermission A permission controlling access to MBeans located in namespaces.
JMXNamespaces Static constants and utility methods to help work with JMX name spaces.
JMXNamespaceView This class makes it possible to navigate easily within a hierarchical namespace view.
JMXRemoteNamespace A JMXNamespace that will connect to a remote MBeanServer by creating a JMXConnector from a JMXServiceURL.
MBeanServerConnectionWrapper An object of this class implements the MBeanServer interface and, for each of its methods forwards the request to a wrapped MBeanServerConnection object.
MBeanServerSupport Base class for custom implementations of the MBeanServer interface.
VirtualEventManager This class maintains a list of subscribers for ObjectName patterns and allows a notification to be sent to all subscribers for a given ObjectName.
 

Package javax.management.namespace Description

The javax.management.namespace package makes it possible to federate MBeanServers into a hierarchical name space.

What Is a Name Space?

A name space is like an MBeanServer within an MBeanServer. Just as a file system folder can contain another file system folder, an MBeanServer can contain another MBeanServer. Similarly, just as a remote folder on a remote disk can be mounted on a parent folder on a local disk, a remote name space in a remote MBeanServer can be mounted on a name space in a local parent MBeanServer.

The javax.management.namespace API thus makes it possible to create a hierarchy of MBean servers federated in a hierarchical name space inside a single MBeanServer.

How To Create a Name Space?

To create a name space, you only need to register a JMXNamespace MBean in an MBean server. We have seen that a namespace is like an MBeanServer within an MBeanServer, and therefore, it is possible to create a namespace that shows the content of another MBeanServer. The simplest case is when that MBeanServer is another MBeanServer created by the MBeanServerFactory as shown in the extract below:

  final MBeanServer server = ....;
  final String namespace = "foo";
  final ObjectName namespaceName = JMXNamespaces.getNamespaceObjectName(namespace);
  server.registerMBean(new JMXNamespace(MBeanServerFactory.newMBeanServer()),
                      namespaceName);
  

To navigate in namespaces and view their content, the easiest way is to use an instance of JMXNamespaceView. For instance, given the server above, in which we created a namespace "foo", it is possible to create a JMXNamespaceView that will make it possible to navigate easily in the namespaces and sub-namespaces of that server:

  // create a namespace view for 'server'
  final JMXNamespaceView view = new JMXNamespaceView(server);

  // list all top level namespaces in 'server'
  System.out.println("List of namespaces: " + Arrays.toString(view.list()));

  // go down into namespace 'foo': provides a namespace view of 'foo' and its
  // sub namespaces...
  final JMXNamespaceView foo = view.down("foo");

  // list all MBeans contained in namespace 'foo'
  System.out.println(foo.where() + " contains: " +
         foo.getMBeanServerConnection().queryNames(null,null));
  

It is also possible to create more complex namespaces, such as namespaces that point to MBean servers located in remote JVMs.

For instance, to mount the MBeanServer accessible at service:jmx:rmi:///jndi/rmi://localhost:9000/jmxrmi in a name space "foo" inside the platform MBeanServer you would write the following piece of code:

      final JMXServiceURL sourceURL =
         new JMXServiceURL("service:jmx:rmi:///jndi/rmi://localhost:9000/jmxrmi");
      final MBeanServer platform = ManagementFactory.getPlatformMBeanServer();
      final Map<String,Object> options = Collections.emptyMap();
      final JMXRemoteNamespace mbean = JMXRemoteNamespace.
         newJMXRemoteNamespace(sourceURL, options);
      final ObjectName name = JMXNamespaces.getNamespaceObjectName("foo");
      final ObjectInstance ref = platform.registerMBean(mbean,name);
      platform.invoke(ref.getObjectName(),"connect",null,null);
  

What Does a Name Space Look Like?

We have seen that JMXNamespaceView class provides an easy way to navigate within namespaces. It is however also possible to interact with namespaces directly from the top level MBeanServer in which they have been created. From the outside, a name space only appears as a special MBean in the MBean server. There's nothing much you can do with this MBean directly.

For instance, let's assume you have registered a JMXRemoteNamespaceMBean to manage the name space "foo".
If you query for platform.queryNames("*//:*",null), then you will see one MBean named "foo//:type=JMXNamespace".
This is the JMXNamespace MBean which is in charge of handling the namespace "foo".

In fact, name space handler MBeans are instances of the class JMXNamespace - or instances of a subclass of that class. They have a special ObjectName defined by JMXNamespaces.getNamespaceObjectName.
JMXNamespace instances are able to return an MBeanServer which corresponds to the MBeanServer within (= the name space itself).

So how does it work? How can you see the MBeans contained in the new name space?

In order to address scalability issues, MBeans registered in namespaces (such as our namespace "foo" above) can not be seen with mbeanServer.queryNames("*:*",null). To see the MBeans contained in a namespace, you can use one of these methods:

  1. You can use the JMXNamespaceView class shown above,
  2. or you can directly look for MBeans whose names match "foo//*:*",
  3. or you can narrow down to the namespace and obtain an MBeanServer proxy that corresponds to an MBeanServer view of that namespace. The JMXNamespaces class provides a static method that allows you to narrow down to a name space, by calling JMXNamespaces.narrowToNamespace.

Using Name Space Prefixes

As we have explained above, MBeans contained in name spaces are not returned by server.queryNames(null,null) - or server.queryNames(ObjectName.WILDCARD,null).
However, these MBeans can still be accessed from the top level MBeanServer interface, without using any API specific to the version 2.0 of the JMX API, simply by using object names with name space prefixes:
To list MBeans contained in a namespace "foo" you can query for MBeans whose names match "foo//*:*", as shown earlier in this document:

         server.queryNames(new ObjectName("foo//*:*", null);
         // or equivalently:
         server.queryNames(JMXNamespaces.getWildcardFor("foo"), null);
      
This will return a list of MBean names whose domain name starts with foo//.

Using these names, you can invoke any operation on the corresponding MBeans. For instance, to get the MBeanInfo of an MBean contained in name space "foo" (assuming the name of the MBean within its name space is domain:type=Thing, then simply call:

         server.getMBeanInfo(new ObjectName("foo//domain:type=Thing"));
      
An easier way to access MBeans contained in a name space is to cd inside the name space, as shown in the following paragraph.

Although ObjectName patterns where the characters * and ? appear in the namespace path are legal, they are not valid in the name parameter of the MBean Server queryNames and queryMBeans methods.
When invoking queryNames or queryMBeans, only ObjectNames of the form:
[namespace-without-pattern//]*[pattern-without-namespace]:key-properties-with-or-without-pattern are valid.
In other words: in the case of queryNames and queryMBeans, if a namespace path is present, it must not contain any pattern.

There is no such restriction for the query parameter of these methods. However, it must be noted that the query parameter will be evaluated in the context of the namespace where the MBeans selected by the pattern specified in name are located. This means that if query parameter is an ObjectName pattern that contains a namespace path, no MBean name will match and the result of the query will be empty.
In other words:

Narrowing Down Into a Name Spaces

As we have seen, name spaces are like MBean servers within MBean servers. Therefore, it is possible to view a name space just as if it were an other MBean server. This is similar to opening a sub folder from a parent folder.
This operation is illustrated in the code extract below:

          final MBeanServer foo =
                JMXNamespaces.narrowToNamespace(platform, "foo");
          final MBeanInfo info =
                foo.getMBeanInfo(new ObjectName("domain:type=Thing"));
      
The MBeanServer returned by JMXNamespaces.narrowToNamespace is an MBeanServer view that narrows down into a given namespace. The MBeans contained inside that namespace can now be accessed by their regular local name.
The MBean server obtained by narrowing down to name space "foo" behaves just like a regular MBean server. However, it may sometimes throw an UnsupportedOperationException wrapped in a RuntimeOperationsException if you try to call an operation which is not supported by the underlying name space handler.
For instance, registerMBean is not supported for name spaces mounted from remote MBean servers.

Note: If you have a deep hierarchy of namespaces, and if you are switching from one namespace to another in the course of your application, it might be more convenient to use a JMXNamespaceView in order to navigate in your namespaces.

Different Types of Name Spaces

This API lets you create several types of name spaces:

Name Spaces And Special Operations

MBean Naming considerations aside, Name Spaces are transparent for most MBeanServer operations. There are however a few exceptions:

Crossing Several Name Spaces

Just as folders can contain other folders, name spaces can contain other name spaces. For instance, if an MBeanServer S1 containing a name space "bar" is mounted in another MBeanServer S2 with name space "foo", then an MBean M1 named "domain:type=Thing" in namespace "bar" will appear as "foo//bar//domain:type=Thing" in MBeanServer S2.

When accessing the MBean M1 from server S2, the method call will traverse in a cascade MBeanServer S2, then the name space handler for name space "foo", then MBeanServer S1, before coming to the name space handler for name space "bar". Any operation invoked on the MBean from a "top-level" name space will therefore need to traverse all the name spaces along the name space path until it eventually reaches the named MBean. This means that an operation like registerMBean for instance, can only succeed if all the name spaces along the path support it.

Narrowing to a nested name space works just the same as narrowing to a top level name space:

          final MBeanServer S2 = .... ;
          final MBeanServer bar =
                JMXNamespaces.narrowToNamespace(S2, "foo//bar");
          final MBeanInfo info =
                foo.getMBeanInfo(new ObjectName("domain:type=Thing"));
      

Name Spaces And Operation Results

Operation results, as well as attribute values returned by an MBean contained in a name space must be interpreted in the context of that name space.
In other words, if an MBean in name space "foo" has an attribute of type ObjectName, then it must be assumed that the ObjectName returned by that MBean is relative to name space "foo".
The same rule aplies for MBean names that can be returned by operations invoked on such an MBean. If one of the MBean operations return, say, a Set<ObjectName> then those MBean names must also be assumed to be relative to name space "foo".

In the usual case, a JMX client will first narrow to a name space before invoking any operation on the MBeans it contains. In that case the names returned by the MBean invoked can be directly fed back to the narrowed connection.
If however, the JMX client directly invoked the MBean from a higher name space, without having narrowed to that name space first, then the names that might be returned by that MBean will not be directly usable - the JMX client will need to either narrow to the name space before using the returned names, or convert the names to the higher level name space context.
The JMXNamespaces class provides methods that can be used to perform that conversion.

Name Spaces And Notifications

As already explained, name spaces are very similar to MBeanServers. It is thus possible to get MBeanServerNotifications when MBeans are added or removed within a name space, by registering with the MBeanServerDelegate MBean of the corresponding name space.
However, it must be noted that the notifications emitted by a name space must be interpreted in the context of that name space. For instance, if an MBean "domain:type=Thing" contained in namespace "foo//bar" emits a notification, the source of the notification will be "domain:type=Thing", not "foo//bar//domain:type=Thing".
It is therefore recommended to keep track of the name space information when registering a listener with an MBean contained in a name space, especially if the same listener is used to receive notifications from different name spaces. An easy solution is to use the handback, as illustrated in the code below.

            final MBeanServer server = ...;
            final NotificationListener listener = new NotificationListener() {
                public void handleNotification(Notification n, Object handback) {
                    if (!(n instanceof MBeanServerNotification)) {
                        System.err.println("Error: expected MBeanServerNotification");
                        return;
                    }
                    final MBeanServerNotification mbsn =
                            (MBeanServerNotification) n;

                    // We will pass the namespace path in the handback.
                    //
                    // The received notification must be interpreted in
                    // the context of its source - therefore
                    // mbsn.getMBeanName() does not include the name space
                    // path...
                    //
                    final String namespace = (String) handback;
                    System.out.println("Received " + mbsn.getType() +
                            " for MBean " + mbsn.getMBeanName() +
                            " from name space " + namespace);
                }
            };
            server.addNotificationListener(JMXNamespaces.insertPath("foo//bar",
                    MBeanServerDelegate.DELEGATE_NAME),listener,null,"foo//bar");
            server.addNotificationListener(JMXNamespaces.insertPath("foo//joe",
                    MBeanServerDelegate.DELEGATE_NAME),listener,null,"foo//joe");
          

JMX Connectors may require some configuration in order to be able to forward notifications from MBeans located in name spaces. The RMI JMX Connector Server in the Java SE 7 platform is configured by default to internally use the new event service on the server side. When the connector server is configured in this way, JMX clients which use the old JMX Notifications mechanism (such as clients running on prior versions of the JDK) will be able to to receive notifications from MBeans located in sub name spaces. This is because the connector server will transparently delegate their subscriptions to the underlying event service. In summary:

These configuration issues apply at each node in the name space path, whenever the name space points to a remote server. The JMXRemoteNamespace can be configured in such a way that it will explicitly use an EventClient when forwarding subscription to the remote side. Note that this can be unnecessary (and a waste of resources) if the underlying JMXConnector returned by the JMXConnectorFactory (client side) already uses the event service to register for notifications with the server side.

Name Spaces And Access Control

Access to MBeans exposed through JMX namespaces is controlled by jmx namespace permissions. These permissions are checked by the MBeanServer in which the JMXNamespace MBean is registered. This is described in details in the JMXNamespace class.

To implement a "firewall-like" access control in a JMX agent you can also place an MBeanServerForwarder in the JMX Connector Server which exposes the top-level MBeanServer of your application. This MBeanServerForwarder will be able to perform authorization checks for all MBeans, including those located in sub name spaces.

For a tighter access control we recommend using a security manager.

Since:
1.7


Java™ Platform
Standard Ed. 7

DRAFT ea-b76

Submit a bug or feature

Copyright 2009 Sun Microsystems, Inc. All Rights Reserved. Use is subject to license terms.