|
Java™ Platform Standard Ed. 7 DRAFT ea-b76 |
|||||||||
| PREV PACKAGE NEXT PACKAGE | FRAMES NO FRAMES | |||||||||
javax.management.namespace package makes it possible
to federate MBeanServers into a hierarchical name space.
See:
Description
| 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 | 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. |
The javax.management.namespace package makes it possible
to federate MBeanServers into a hierarchical 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.
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);
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:
JMXNamespaceView
class shown above,
"foo//*:*",
JMXNamespaces.narrowToNamespace.
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:
queryNames("foo//bar//?a?:*","b?z:type=Monitor,*") will select
all MBeans in namespace foo//bar whose names match both
?a?:* and b?z:type=Monitor,*, butqueryNames("foo//bar//?a?:*","foo//bar//b?z:type=Monitor,*")
will select nothing because no name matching ?a?:* will
also match foo//bar//b?z:type=Monitor,*.
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. "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.
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.
This API lets you create several types of name spaces:
JMXRemoteNamespace to create
remote name spaces, mounted from
a remote sub MBeanServer source, as shown
earlier in this document.
JMXNamespace to create
local name spaces,
by providing a direct reference to another MBeanServer
instance living in the same JVM.
MBeanServerSupport, and passing an instance of
your own subclass to a JMXNamespace.
JMXNamespace. This is however discouraged.
MBean Naming considerations aside, Name Spaces are transparent for
most MBeanServer operations. There are however a few
exceptions:
MBeanServer only operations - these are the operations which are
supported by MBeanServer but
are not present in MBeanServerConnection. Since a name space can be a local view of
a remote MBeanServer, accessible only through an
MBeanServerConnection, these
kinds of operations are not always supported.
registerMBean:
The registerMBean
operation is not supported by most name spaces. A call
to
MBeanServer server = ....;
ThingMBean mbean = new Thing(...);
ObjectName name = new ObjectName("foo//domain:type=Thing");
server.registerMBean(mbean, name);
will usually fail, unless the name space
"foo" is a local name
space. In the case where you attempt to cross
multiple name spaces, then all name spaces in the
path must support the registerMBean operation
in order for it to succeed.createMBean -
although some special
considerations can also apply.
getClassLoader:
Similarly to registerMBean,
and for the same reasons, getClassLoader will usually fail, unless the
class loader is an MBean registered in a
local name space.
getClassLoaderFor:
The implementation of getClassLoaderFor also depends on which
type of name space
handler is used across the namespace path.
A local name space will usually
be able to implement this method just as a real
MBeanServer would. A
remote name space will usually
return the default class loader configured on the
internal JMXConnector used to connect to the remote server.
When a JMXRemoteNamespace is used to connect to a
remote server that contains MBeans which export
custom types, the JMXRemoteNamespace must thus be configured with
an options map such that the underlying connector
can obtain a default class loader able
to handle those types.
Other types of name spaces may implement this method as best as they can.
MBean creation
MBean creation through createMBean might not be supported by all
name spaces: local name spaces and
remote name spaces will usually
support it, but virtual name
spaces and custom name
spaces might not.
In that case, they will throw an UnsupportedOperationException usually wrapped into an MBeanRegistrationException.
Notifications
Some namespaces might not support JMX Notifications. In that
case, a call to add or remove notification listener for an
MBean contained in that name space will raise a
RuntimeOperationsException wrapping an UnsupportedOperationException exception.
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"));
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.
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:
MBeanServer
through a JMX Connector, you will need to make sure that the
connector server uses the new event service in order to register for notifications. If the
connector server doesn't use the event service, only clients
which explicitly use the new event service will be able to register for notifications
with MBeans located in sub name spaces.
MBeanServerConnection add / remove notification
listener methods transparently. Otherwise, only clients which
explicitly use the new event service will be able to receive notifications from
MBeans contained in sub name spaces.
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.
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.
|
Java™ Platform Standard Ed. 7 DRAFT ea-b76 |
|||||||||
| PREV PACKAGE NEXT PACKAGE | FRAMES NO FRAMES | |||||||||
Copyright 2009 Sun Microsystems, Inc. All Rights Reserved. Use is subject to license terms.