diff -r a9a142fcf1b5 -r bbc2d15aaf7a jdk/src/share/classes/javax/management/namespace/package-info.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/share/classes/javax/management/namespace/package-info.java Thu Sep 04 14:46:36 2008 +0200 @@ -0,0 +1,597 @@ +/* + * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/** + *
The javax.management.namespace
package makes it possible
+ * to federate MBeanServers into a hierarchical name space.
+ * A name space is like an {@link javax.management.MBeanServer} within + * an {@code MBeanServer}. Just as a file system folder can contain + * another file system folder, an {@code MBeanServer} can contain another + * {@code 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 {@code MBeanServer} can be mounted on a name + * space in a local parent {@code 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 {@code MBeanServer}.
+ *
+ * To create a name space, you only need to register a + * {@link javax.management.namespace.JMXNamespace} MBean in + * an MBean server. We have seen that a namespace is like + * an {@code MBeanServer} within an {@code MBeanServer}, and + * therefore, it is possible to create a namespace that shows the + * content of another {@code MBeanServer}. The simplest case is + * when that {@code MBeanServer} is another {@code MBeanServer} + * created by the {@link javax.management.MBeanServerFactory} as + * shown in the extract below: + *
+ *+ * final MBeanServer server = ....; + * final String namespace = "foo"; + * final ObjectName namespaceName = {@link javax.management.namespace.JMXNamespaces#getNamespaceObjectName + * 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 {@link javax.management.namespace.JMXNamespaceView}. For instance, given + * the {@code server} above, in which we created a namespace {@code "foo"}, + * it is possible to create a {@code 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({@link javax.management.namespace.JMXNamespaceView#list() view.list()})); + * + * // go down into namespace 'foo': provides a namespace view of 'foo' and its + * // sub namespaces... + * final JMXNamespaceView foo = {@link javax.management.namespace.JMXNamespaceView#down view.down("foo")}; + * + * // list all MBeans contained in namespace 'foo' + * System.out.println({@link javax.management.namespace.JMXNamespaceView#where() foo.where()} + " contains: " + + * {@link javax.management.namespace.JMXNamespaceView#getMBeanServerConnection 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 {@code "foo"} inside the {@linkplain
+ * java.lang.management.ManagementFactory#getPlatformMBeanServer 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 = {@link + * javax.management.namespace.JMXRemoteNamespace JMXRemoteNamespace}. + * {@link javax.management.namespace.JMXRemoteNamespace#newJMXRemoteNamespace newJMXRemoteNamespace(sourceURL, options)}; + * final ObjectName name = {@link javax.management.namespace.JMXNamespaces JMXNamespaces}.{@link javax.management.namespace.JMXNamespaces#getNamespaceObjectName(String) getNamespaceObjectName("foo")}; + * final ObjectInstance ref = platform.registerMBean(mbean,name); + * platform.invoke(ref.getObjectName(),"connect",null,null); + *+ * + *
+ * We have seen that {@link javax.management.namespace.JMXNamespaceView} class + * provides an easy way to navigate within namespaces. It is however also + * possible to interact with namespaces directly from the top level + * {@code 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 {@link
+ * javax.management.namespace.JMXRemoteNamespaceMBean
+ * JMXRemoteNamespaceMBean} to manage the name space {@code "foo"}.
+ *
If you query for
+ * platform.queryNames("*//:*",null)
, then you will see
+ * one MBean named {@code "foo//:type=JMXNamespace"}.
+ *
This is the {@link javax.management.namespace.JMXNamespace}
+ * MBean which is in charge of handling the namespace {@code "foo"}.
+ *
+ * In fact, name space handler MBeans are instances of
+ * the class {@link javax.management.namespace.JMXNamespace} - or
+ * instances of a subclass of that class.
+ * They have a special {@link javax.management.ObjectName} defined by
+ * {@link javax.management.namespace.JMXNamespaces#getNamespaceObjectName
+ * JMXNamespaces.getNamespaceObjectName}.
+ * {@link javax.management.namespace.JMXNamespace} instances are able
+ * to return an {@link
+ * javax.management.namespace.JMXNamespace#getSourceServer 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 {@code "foo"} above) can not be + * seen with {@code mbeanServer.queryNames("*:*",null)}. To see the MBeans + * contained in a namespace, you can use one of these methods: + *
+ *
+ * As we have explained above, MBeans contained in name
+ * spaces are not returned by {@code server.queryNames(null,null)} - or
+ * server.queryNames({@link javax.management.ObjectName#WILDCARD ObjectName.WILDCARD},null)
.
+ *
+ * However, these MBeans can still be accessed from the top level
+ * {@code 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 {@code "foo"} you can
+ * query for MBeans whose names match {@code "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 {@code foo//}. + *
+ * Using these names, you can invoke any operation on the corresponding + * MBeans. For instance, to get the {@link javax.management.MBeanInfo + * MBeanInfo} of an MBean + * contained in name space {@code "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. + * + * + *
+ * 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 {@code MBeanServer} returned by {@link + * javax.management.namespace.JMXNamespaces#narrowToNamespace(MBeanServer,String) + * JMXNamespaces.narrowToNamespace} is an {@code MBeanServer} view that + * narrows down into a given namespace. The MBeans contained inside that + * namespace can now be accessed by their regular local name.
+ * 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 + * {@link javax.management.namespace.JMXNamespaceView} + * in order to navigate in your namespaces. + *
+ * + *+ * This API lets you create several types of name spaces: + *
+ * MBean Naming considerations aside, Name Spaces are transparent for + * most {@code MBeanServer} operations. There are however a few + * exceptions: + *
+ *MBeanServer only operations - these are the operations which are + * supported by {@link javax.management.MBeanServer MBeanServer} but + * are not present in {@link + * javax.management.MBeanServerConnection + * MBeanServerConnection}. Since a name space can be a local view of + * a remote {@code MBeanServer}, accessible only through an + * {@code MBeanServerConnection}, these + * kinds of operations are not always supported.
+ *registerMBean:
+ *The {@link javax.management.MBeanServer#registerMBean + * 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 + * {@code "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 {@code registerMBean} operation + * in order for it to succeed.
getClassLoader:
+ * Similarly to registerMBean,
+ * and for the same reasons, {@link
+ * javax.management.MBeanServer#getClassLoader
+ * getClassLoader} will usually fail, unless the
+ * class loader is an MBean registered in a
+ * local name space.
+ *
getClassLoaderFor:
+ *The implementation of {@link + * javax.management.MBeanServer#getClassLoaderFor + * 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 + * {@code MBeanServer} would. A + * remote name space will usually + * return the default class loader configured on the + * internal {@link javax.management.remote.JMXConnector + * JMXConnector} used to connect to the remote server. + * When a {@link + * javax.management.namespace.JMXRemoteNamespace + * JMXRemoteNamespace} is used to connect to a + * remote server that contains MBeans which export + * custom types, the {@link + * javax.management.namespace.JMXRemoteNamespace + * 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 {@link + * javax.management.MBeanServerConnection#createMBean + * 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 {@link + * java.lang.UnsupportedOperationException + * UnsupportedOperationException} usually wrapped into an {@link + * javax.management.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 + * {@link javax.management.RuntimeOperationsException + * RuntimeOperationsException} wrapping an {@link + * java.lang.UnsupportedOperationException + * UnsupportedOperationException} exception. + *
+ *+ * Just as folders can contain other folders, name spaces can contain + * other name spaces. For instance, if an {@code MBeanServer} S1 + * containing a name space {@code "bar"} is mounted in another + * {@code MBeanServer} S2 with name space {@code "foo"}, then + * an MBean M1 named {@code "domain:type=Thing"} in namespace + * {@code "bar"} will appear as {@code "foo//bar//domain:type=Thing"} in + * {@code MBeanServer} S2. + *
+ *+ * When accessing the MBean M1 from server S2, the + * method call will traverse in a cascade {@code MBeanServer} S2, + * then the name space handler for name space {@code "foo"}, then + * {@code MBeanServer} S1, before coming to the name space + * handler for name space {@code "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 {@code ObjectName}, then it must be assumed that the
+ * {@code 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 {@code Set
+ *
+ * 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 {@link javax.management.namespace.JMXNamespaces JMXNamespaces}
+ * class provides methods that can be used to perform that conversion.
+ *
+ * As already explained, name spaces are very
+ * similar to {@code MBeanServer}s. It is thus possible to get
+ * {@link javax.management.MBeanServerNotification MBeanServerNotifications}
+ * when MBeans are added or removed within a name space, by registering
+ * with the {@link javax.management.MBeanServerDelegate
+ * 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 {@code "domain:type=Thing"} contained in
+ * namespace "foo//bar" emits a notification, the source of the
+ * notification will be {@code "domain:type=Thing"}, not
+ * {@code "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 {@linkplain javax.management.event 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 {@linkplain + * javax.management.event 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 + * {@link javax.management.namespace.JMXRemoteNamespace + * JMXRemoteNamespace} can be configured in such a way that it will + * explicitly use an {@link javax.management.event.EventClient 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 + * {@linkplain javax.management.event event service} to register for + * notifications with the server side. + *
+ * + *+ * Access to MBeans exposed through JMX namespaces is controlled by + * {@linkplain javax.management.namespace.JMXNamespacePermission + * jmx namespace permissions}. These permissions are checked by the + * MBeanServer in which the {@link + * javax.management.namespace.JMXNamespace JMXNamespace} MBean is registered. + * This is described in + * details in the {@link + * javax.management.namespace.JMXNamespace JMXNamespace} class. + *
+ *+ * To implement a "firewall-like" access control in a JMX agent you + * can also place an {@link + * javax.management.remote.MBeanServerForwarder} in the JMX Connector + * Server which exposes the top-level MBeanServer of your application. + * This {@code 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 {@link + * java.lang.SecurityManager security manager}. + *
+ * @since 1.7 + * + **/ + +package javax.management.namespace; +