|
1 /* |
|
2 * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved. |
|
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
|
4 * |
|
5 * This code is free software; you can redistribute it and/or modify it |
|
6 * under the terms of the GNU General Public License version 2 only, as |
|
7 * published by the Free Software Foundation. Sun designates this |
|
8 * particular file as subject to the "Classpath" exception as provided |
|
9 * by Sun in the LICENSE file that accompanied this code. |
|
10 * |
|
11 * This code is distributed in the hope that it will be useful, but WITHOUT |
|
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
|
14 * version 2 for more details (a copy is included in the LICENSE file that |
|
15 * accompanied this code). |
|
16 * |
|
17 * You should have received a copy of the GNU General Public License version |
|
18 * 2 along with this work; if not, write to the Free Software Foundation, |
|
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
|
20 * |
|
21 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, |
|
22 * CA 95054 USA or visit www.sun.com if you need additional information or |
|
23 * have any questions. |
|
24 */ |
|
25 |
|
26 /** |
|
27 * <p>The <code>javax.management.namespace</code> package makes it possible |
|
28 * to federate MBeanServers into a hierarchical name space.</p> |
|
29 * |
|
30 * <h3 id="WhatIs">What Is a Name Space?</h3> |
|
31 * <p> |
|
32 * A name space is like an {@link javax.management.MBeanServer} within |
|
33 * an {@code MBeanServer}. Just as a file system folder can contain |
|
34 * another file system folder, an {@code MBeanServer} can contain another |
|
35 * {@code MBeanServer}. Similarly, just as a remote folder on a remote |
|
36 * disk can be mounted on a parent folder on a local disk, a remote name |
|
37 * space in a remote {@code MBeanServer} can be mounted on a name |
|
38 * space in a local parent {@code MBeanServer}. |
|
39 * </p> |
|
40 * <p> |
|
41 * The <code>javax.management.namespace</code> API thus makes it possible to |
|
42 * create a hierarchy of MBean servers federated in a hierarchical name |
|
43 * space inside a single {@code MBeanServer}. |
|
44 * </p> |
|
45 * <h3 id="HowToCreate">How To Create a Name Space?</h3> |
|
46 * <p> |
|
47 * To create a name space, you only need to register a |
|
48 * {@link javax.management.namespace.JMXNamespace} MBean in |
|
49 * an MBean server. We have seen that a namespace is like |
|
50 * an {@code MBeanServer} within an {@code MBeanServer}, and |
|
51 * therefore, it is possible to create a namespace that shows the |
|
52 * content of another {@code MBeanServer}. The simplest case is |
|
53 * when that {@code MBeanServer} is another {@code MBeanServer} |
|
54 * created by the {@link javax.management.MBeanServerFactory} as |
|
55 * shown in the extract below: |
|
56 * </p> |
|
57 * <pre> |
|
58 * final MBeanServer server = ....; |
|
59 * final String namespace = "foo"; |
|
60 * final ObjectName namespaceName = {@link javax.management.namespace.JMXNamespaces#getNamespaceObjectName |
|
61 * JMXNamespaces.getNamespaceObjectName(namespace)}; |
|
62 * server.registerMBean(new JMXNamespace(MBeanServerFactory.newMBeanServer()), |
|
63 * namespaceName); |
|
64 * </pre> |
|
65 * <p id="NamespaceView"> |
|
66 * To navigate in namespaces and view their content, the easiest way is |
|
67 * to use an instance of {@link javax.management.namespace.JMXNamespaceView}. For instance, given |
|
68 * the {@code server} above, in which we created a namespace {@code "foo"}, |
|
69 * it is possible to create a {@code JMXNamespaceView} that will make it |
|
70 * possible to navigate easily in the namespaces and sub-namespaces of that |
|
71 * server: |
|
72 * </p> |
|
73 * <pre> |
|
74 * // create a namespace view for 'server' |
|
75 * final JMXNamespaceView view = new JMXNamespaceView(server); |
|
76 * |
|
77 * // list all top level namespaces in 'server' |
|
78 * System.out.println("List of namespaces: " + Arrays.toString({@link javax.management.namespace.JMXNamespaceView#list() view.list()})); |
|
79 * |
|
80 * // go down into namespace 'foo': provides a namespace view of 'foo' and its |
|
81 * // sub namespaces... |
|
82 * final JMXNamespaceView foo = {@link javax.management.namespace.JMXNamespaceView#down view.down("foo")}; |
|
83 * |
|
84 * // list all MBeans contained in namespace 'foo' |
|
85 * System.out.println({@link javax.management.namespace.JMXNamespaceView#where() foo.where()} + " contains: " + |
|
86 * {@link javax.management.namespace.JMXNamespaceView#getMBeanServerConnection foo.getMBeanServerConnection()}.queryNames(null,null)); |
|
87 * </pre> |
|
88 * <p> |
|
89 * It is also possible to create more complex namespaces, such as namespaces |
|
90 * that point to MBean servers located in remote JVMs. |
|
91 * </p> |
|
92 * <p> |
|
93 * For instance, to mount the MBeanServer accessible |
|
94 * at <code>service:jmx:rmi:///jndi/rmi://localhost:9000/jmxrmi</code> |
|
95 * in a name space {@code "foo"} inside the {@linkplain |
|
96 * java.lang.management.ManagementFactory#getPlatformMBeanServer platform |
|
97 * MBeanServer} you would write the following piece of code: |
|
98 * </p> |
|
99 * <pre> |
|
100 * final JMXServiceURL sourceURL = |
|
101 * new JMXServiceURL("service:jmx:rmi:///jndi/rmi://localhost:9000/jmxrmi"); |
|
102 * final MBeanServer platform = ManagementFactory.getPlatformMBeanServer(); |
|
103 * final Map<String,Object> options = Collections.emptyMap(); |
|
104 * final JMXRemoteNamespace mbean = {@link |
|
105 * javax.management.namespace.JMXRemoteNamespace JMXRemoteNamespace}. |
|
106 * {@link javax.management.namespace.JMXRemoteNamespace#newJMXRemoteNamespace newJMXRemoteNamespace(sourceURL, options)}; |
|
107 * final ObjectName name = {@link javax.management.namespace.JMXNamespaces JMXNamespaces}.{@link javax.management.namespace.JMXNamespaces#getNamespaceObjectName(String) getNamespaceObjectName("foo")}; |
|
108 * final ObjectInstance ref = platform.registerMBean(mbean,name); |
|
109 * platform.invoke(ref.getObjectName(),"connect",null,null); |
|
110 * </pre> |
|
111 * |
|
112 * <h3 id="WhatLike">What Does a Name Space Look Like?</h3> |
|
113 * |
|
114 * <p> |
|
115 * We have seen that {@link javax.management.namespace.JMXNamespaceView} class |
|
116 * provides an easy way to navigate within namespaces. It is however also |
|
117 * possible to interact with namespaces directly from the top level |
|
118 * {@code MBeanServer} in which they have been created. |
|
119 * From the outside, a name space only appears as a special MBean in |
|
120 * the MBean server. There's nothing much you can do with this MBean |
|
121 * directly. |
|
122 * </p> |
|
123 * <p> |
|
124 * For instance, let's assume you have registered a {@link |
|
125 * javax.management.namespace.JMXRemoteNamespaceMBean |
|
126 * JMXRemoteNamespaceMBean} to manage the name space {@code "foo"}. |
|
127 * <br>If you query for |
|
128 * <code>platform.queryNames("*//:*",null)</code>, then you will see |
|
129 * one MBean named {@code "foo//:type=JMXNamespace"}. |
|
130 * <br>This is the {@link javax.management.namespace.JMXNamespace} |
|
131 * MBean which is in charge of handling the namespace {@code "foo"}. |
|
132 * </p> |
|
133 * <p> |
|
134 * In fact, name space handler MBeans are instances of |
|
135 * the class {@link javax.management.namespace.JMXNamespace} - or |
|
136 * instances of a subclass of that class. |
|
137 * They have a special {@link javax.management.ObjectName} defined by |
|
138 * {@link javax.management.namespace.JMXNamespaces#getNamespaceObjectName |
|
139 * JMXNamespaces.getNamespaceObjectName}.<br> |
|
140 * {@link javax.management.namespace.JMXNamespace} instances are able |
|
141 * to return an {@link |
|
142 * javax.management.namespace.JMXNamespace#getSourceServer MBeanServer} |
|
143 * which corresponds to the MBeanServer within (= the name space itself). |
|
144 * </p> |
|
145 * <p> |
|
146 * So how does it work? How can you see the MBeans contained in the new |
|
147 * name space? |
|
148 * </p> |
|
149 * <p>In order to address scalability issues, MBeans registered in |
|
150 * namespaces (such as our namespace {@code "foo"} above) can not be |
|
151 * seen with {@code mbeanServer.queryNames("*:*",null)}. To see the MBeans |
|
152 * contained in a namespace, you can use one of these methods: |
|
153 * </p> |
|
154 * <ol> |
|
155 * <li> |
|
156 * You can use the {@link javax.management.namespace.JMXNamespaceView} |
|
157 * class <a href="#NamespaceView">shown above</a>, |
|
158 * </li> |
|
159 * <li> |
|
160 * or you can <a href="#NamespacePrefix">directly look</a> for MBeans |
|
161 * whose names match |
|
162 * {@code "foo//*:*"}, |
|
163 * </li> |
|
164 * <li> |
|
165 * or you can <a href="#ChangeTo">narrow down</a> to the namespace |
|
166 * and obtain an MBeanServer |
|
167 * proxy that corresponds to an MBeanServer view of that namespace. |
|
168 * The JMXNamespaces class provides a static method that |
|
169 * allows you to narrow down to a name space, by calling |
|
170 * {@link javax.management.namespace.JMXNamespaces#narrowToNamespace(MBeanServer,String) |
|
171 * JMXNamespaces.narrowToNamespace}. |
|
172 * </li> |
|
173 * </ol> |
|
174 * |
|
175 * <h3 id="NamespacePrefix">Using Name Space Prefixes</h3> |
|
176 * <p> |
|
177 * As we have explained above, MBeans contained in name |
|
178 * spaces are not returned by {@code server.queryNames(null,null)} - or |
|
179 * <code>server.queryNames({@link javax.management.ObjectName#WILDCARD ObjectName.WILDCARD},null)</code>. |
|
180 * <br> |
|
181 * However, these MBeans can still be accessed from the top level |
|
182 * {@code MBeanServer} interface, without using any API specific to the |
|
183 * version 2.0 of the JMX API, simply by using object names with |
|
184 * name space prefixes: |
|
185 * <br>To list MBeans contained in a namespace {@code "foo"} you can |
|
186 * query for MBeans whose names match {@code "foo//*:*"}, as shown |
|
187 * earlier in this document: |
|
188 * <pre> |
|
189 * server.queryNames(new ObjectName("foo//*:*", null); |
|
190 * // or equivalently: |
|
191 * server.queryNames(JMXNamespaces.getWildcardFor("foo"), null); |
|
192 * </pre> |
|
193 * This will return a list of MBean names whose domain name starts |
|
194 * with {@code foo//}. |
|
195 * </p><p> |
|
196 * Using these names, you can invoke any operation on the corresponding |
|
197 * MBeans. For instance, to get the {@link javax.management.MBeanInfo |
|
198 * MBeanInfo} of an MBean |
|
199 * contained in name space {@code "foo"} (assuming |
|
200 * the name of the MBean within its name space is <i>domain:type=Thing</i>, |
|
201 * then simply call: |
|
202 * <pre> |
|
203 * server.getMBeanInfo(new ObjectName("foo//domain:type=Thing")); |
|
204 * </pre> |
|
205 * An easier way to access MBeans contained in a name space is to |
|
206 * <i>cd</i> inside the name space, as shown in the following paragraph. |
|
207 * </p> |
|
208 * |
|
209 * <h3 id="ChangeTo">Narrowing Down Into a Name Spaces</h3> |
|
210 * <p> |
|
211 * As we have seen, name spaces are like MBean servers within MBean servers. |
|
212 * Therefore, it is possible to view a name space just as if it were |
|
213 * an other MBean server. This is similar to opening a sub |
|
214 * folder from a parent folder.<br> |
|
215 * This operation is illustrated in the code extract below: |
|
216 * <pre> |
|
217 * final MBeanServer foo = |
|
218 * JMXNamespaces.narrowToNamespace(platform, "foo"); |
|
219 * final MBeanInfo info = |
|
220 * foo.getMBeanInfo(new ObjectName("domain:type=Thing")); |
|
221 * </pre> |
|
222 * The {@code MBeanServer} returned by {@link |
|
223 * javax.management.namespace.JMXNamespaces#narrowToNamespace(MBeanServer,String) |
|
224 * JMXNamespaces.narrowToNamespace} is an {@code MBeanServer} view that |
|
225 * narrows down into a given namespace. The MBeans contained inside that |
|
226 * namespace can now be accessed by their regular local name. <br> |
|
227 * The MBean server obtained by narrowing down |
|
228 * to name space {@code "foo"} behaves just like a regular MBean server. |
|
229 * However, it may sometimes throw an {@link |
|
230 * java.lang.UnsupportedOperationException UnsupportedOperationException} |
|
231 * wrapped in a JMX exception if you try to call an operation which is not |
|
232 * supported by the underlying name space handler. |
|
233 * <br>For instance, {@link javax.management.MBeanServer#registerMBean |
|
234 * registerMBean} is not supported for name spaces mounted from remote |
|
235 * MBean servers. |
|
236 * </p> |
|
237 * <p> |
|
238 * <u>Note:</u> If you have a deep hierarchy of namespaces, and if you |
|
239 * are switching from one namespace to another in the course of your |
|
240 * application, it might be more convenient to use a |
|
241 * {@link javax.management.namespace.JMXNamespaceView} |
|
242 * in order to navigate in your namespaces. |
|
243 * </p> |
|
244 * |
|
245 * <h3 id="NamespaceTypes">Different Types of Name Spaces</h3> |
|
246 * <p> |
|
247 * This API lets you create several types of name spaces: |
|
248 * <ul> |
|
249 * <li id="RemoteNS"> |
|
250 * You can use the {@link |
|
251 * javax.management.namespace.JMXRemoteNamespace |
|
252 * JMXRemoteNamespace} to create |
|
253 * <b>remote</b> name spaces, mounted from |
|
254 * a remote sub {@code MBeanServer} source, as shown |
|
255 * <a href="#HowToCreate">earlier</a> in this document. |
|
256 * </li> |
|
257 * <li id="LocalNS"> |
|
258 * You can also use {@link |
|
259 * javax.management.namespace.JMXNamespace |
|
260 * JMXNamespace} to create |
|
261 * <b>local</b> name spaces, |
|
262 * by providing a direct reference to another {@code MBeanServer} |
|
263 * instance living in the same JVM. |
|
264 * </li> |
|
265 * <li id="VirtualNS"> |
|
266 * Finally, you can create |
|
267 * name spaces containing <b>virtual</b> MBeans, |
|
268 * by subclassing the {@link |
|
269 * javax.management.namespace.MBeanServerSupport |
|
270 * MBeanServerSupport}, and passing an instance of |
|
271 * your own subclass to a {@link |
|
272 * javax.management.namespace.JMXNamespace JMXNamespace}. |
|
273 * </li> |
|
274 * <li id="CustomNS"> |
|
275 * If none of these classes suit your needs, you can also provide |
|
276 * <b>your own</b> subclass of {@link |
|
277 * javax.management.namespace.JMXNamespace |
|
278 * JMXNamespace}. This is however discouraged. |
|
279 * </li> |
|
280 * </ul> |
|
281 * </p> |
|
282 * |
|
283 * <h3 id="SpecialOp">Name Spaces And Special Operations</h3> |
|
284 * <p> |
|
285 * MBean Naming considerations aside, Name Spaces are transparent for |
|
286 * most {@code MBeanServer} operations. There are however a few |
|
287 * exceptions: |
|
288 * </p> |
|
289 * <ul> |
|
290 * <li> |
|
291 * <p>MBeanServer only operations - these are the operations which are |
|
292 * supported by {@link javax.management.MBeanServer MBeanServer} but |
|
293 * are not present in {@link |
|
294 * javax.management.MBeanServerConnection |
|
295 * MBeanServerConnection}. Since a name space can be a local view of |
|
296 * a remote {@code MBeanServer}, accessible only through an |
|
297 * {@code MBeanServerConnection}, these |
|
298 * kinds of operations are not always supported.</p> |
|
299 * <ul> |
|
300 * <li id="registerMBean"> |
|
301 * <p>registerMBean:</p> |
|
302 * <p> The {@link javax.management.MBeanServer#registerMBean |
|
303 * registerMBean} |
|
304 * operation is not supported by most name spaces. A call |
|
305 * to |
|
306 * <pre> |
|
307 * MBeanServer server = ....; |
|
308 * ThingMBean mbean = new Thing(...); |
|
309 * ObjectName name = new ObjectName("foo//domain:type=Thing"); |
|
310 * server.registerMBean(mbean, name); |
|
311 * </pre> |
|
312 * will usually fail, unless the name space |
|
313 * {@code "foo"} is a <a href="#LocalNS">local</a> name |
|
314 * space. In the case where you attempt to cross |
|
315 * multiple name spaces, then all name spaces in the |
|
316 * path must support the {@code registerMBean} operation |
|
317 * in order for it to succeed.<br> |
|
318 * To create an MBean inside a name space, it is |
|
319 * usually safer to use {@code createMBean} - |
|
320 * although some <a href="#MBeanCreation">special |
|
321 * considerations</a> can also apply. |
|
322 * </p> |
|
323 * <p></p> |
|
324 * </li> |
|
325 * <li id="getClassLoader"> |
|
326 * <p>getClassLoader:</p> |
|
327 * <p> Similarly to <a href="#registerMBean">registerMBean</a>, |
|
328 * and for the same reasons, {@link |
|
329 * javax.management.MBeanServer#getClassLoader |
|
330 * getClassLoader} will usually fail, unless the |
|
331 * class loader is an MBean registered in a |
|
332 * <a href="#LocalNS">local</a> name space.<br> |
|
333 * </p> |
|
334 * </li> |
|
335 * <li id="getClassLoaderFor"> |
|
336 * <p>getClassLoaderFor:</p> |
|
337 * <p> The implementation of {@link |
|
338 * javax.management.MBeanServer#getClassLoaderFor |
|
339 * getClassLoaderFor} also depends on which |
|
340 * <a href="#NamespaceTypes">type of name space</a> |
|
341 * handler is used across the namespace path. |
|
342 * </p> |
|
343 * <p> |
|
344 * A <a href="#LocalNS">local</a> name space will usually |
|
345 * be able to implement this method just as a real |
|
346 * {@code MBeanServer} would. A |
|
347 * <a href="#RemoteNS">remote</a> name space will usually |
|
348 * return the default class loader configured on the |
|
349 * internal {@link javax.management.remote.JMXConnector |
|
350 * JMXConnector} used to connect to the remote server. |
|
351 * When a {@link |
|
352 * javax.management.namespace.JMXRemoteNamespace |
|
353 * JMXRemoteNamespace} is used to connect to a |
|
354 * remote server that contains MBeans which export |
|
355 * custom types, the {@link |
|
356 * javax.management.namespace.JMXRemoteNamespace |
|
357 * JMXRemoteNamespace} must thus be configured with |
|
358 * an options map such that the underlying connector |
|
359 * can obtain a default class loader able |
|
360 * to handle those types. |
|
361 * </p> |
|
362 * <p> |
|
363 * Other <a href="#NamespaceTypes">types of name spaces</a> |
|
364 * may implement this method |
|
365 * as best as they can. |
|
366 * </p> |
|
367 * </li> |
|
368 * </ul> |
|
369 * </li> |
|
370 * <li id="MBeanCreation"> |
|
371 * <p>MBean creation</p> |
|
372 * <p> MBean creation through {@link |
|
373 * javax.management.MBeanServerConnection#createMBean |
|
374 * createMBean} might not be supported by all |
|
375 * name spaces: <a href="#LocalNS">local</a> name spaces and |
|
376 * <a href="#LocalNS">remote</a> name spaces will usually |
|
377 * support it, but <a href="#VirtualNS">virtual</a> name |
|
378 * spaces and <a href="#CustomNS">custom</a> name |
|
379 * spaces might not. |
|
380 * </p> |
|
381 * <p> |
|
382 * In that case, they will throw an {@link |
|
383 * java.lang.UnsupportedOperationException |
|
384 * UnsupportedOperationException} usually wrapped into an {@link |
|
385 * javax.management.MBeanRegistrationException}. |
|
386 * </p> |
|
387 * </li> |
|
388 * <li id="Notifications"> |
|
389 * <p>Notifications</p> |
|
390 * <p> Some namespaces might not support JMX Notifications. In that |
|
391 * case, a call to add or remove notification listener for an |
|
392 * MBean contained in that name space will raise a |
|
393 * {@link javax.management.RuntimeOperationsException |
|
394 * RuntimeOperationsException} wrapping an {@link |
|
395 * java.lang.UnsupportedOperationException |
|
396 * UnsupportedOperationException} exception. |
|
397 * </p> |
|
398 * </li> |
|
399 * </ul> |
|
400 * |
|
401 * <h3 id="CrossingNamespace">Crossing Several Name Spaces</h3> |
|
402 * <p> |
|
403 * Just as folders can contain other folders, name spaces can contain |
|
404 * other name spaces. For instance, if an {@code MBeanServer} <i>S1</i> |
|
405 * containing a name space {@code "bar"} is mounted in another |
|
406 * {@code MBeanServer} <i>S2</i> with name space {@code "foo"}, then |
|
407 * an MBean <i>M1</i> named {@code "domain:type=Thing"} in namespace |
|
408 * {@code "bar"} will appear as {@code "foo//bar//domain:type=Thing"} in |
|
409 * {@code MBeanServer} <i>S2</i>. |
|
410 * </p> |
|
411 * <p> |
|
412 * When accessing the MBean <i>M1</i> from server <i>S2</i>, the |
|
413 * method call will traverse in a cascade {@code MBeanServer} <i>S2</i>, |
|
414 * then the name space handler for name space {@code "foo"}, then |
|
415 * {@code MBeanServer} <i>S1</i>, before coming to the name space |
|
416 * handler for name space {@code "bar"}. Any operation invoked |
|
417 * on the MBean from a "top-level" name space will therefore need to |
|
418 * traverse all the name spaces along the name space path until |
|
419 * it eventually reaches the named MBean. This means that an operation |
|
420 * like <a href="#registerMBean">registerMBean</a> for instance, |
|
421 * can only succeed if all the name spaces along the path support it. |
|
422 * </p> |
|
423 * <p> |
|
424 * Narrowing to a nested name space works just the same as narrowing |
|
425 * to a top level name space: |
|
426 * <pre> |
|
427 * final MBeanServer S2 = .... ; |
|
428 * final MBeanServer bar = |
|
429 * JMXNamespaces.narrowToNamespace(S2, "foo//bar"); |
|
430 * final MBeanInfo info = |
|
431 * foo.getMBeanInfo(new ObjectName("domain:type=Thing")); |
|
432 * </pre> |
|
433 * </p> |
|
434 * |
|
435 * <h3 id="OperationResult">Name Spaces And Operation Results</h3> |
|
436 * <p> |
|
437 * Operation results, as well as attribute values returned by an MBean |
|
438 * contained in a name space must be interpreted in the context of that |
|
439 * name space.<br> |
|
440 * In other words, if an MBean in name space "foo" has an attribute of |
|
441 * type {@code ObjectName}, then it must be assumed that the |
|
442 * {@code ObjectName} returned by that MBean is relative to |
|
443 * name space "foo".<br> |
|
444 * The same rule aplies for MBean names that can be returned by |
|
445 * operations invoked on such an MBean. If one of the MBean operations |
|
446 * return, say, a {@code Set<ObjectName>} then those MBean names must |
|
447 * also be assumed to be relative to name space "foo".<br> |
|
448 * </p> |
|
449 * <p> |
|
450 * In the usual case, a JMX client will first |
|
451 * <a href="#ChangeTo">narrow to a name space</a> before invoking |
|
452 * any operation on the MBeans it contains. In that case the names |
|
453 * returned by the MBean invoked can be directly fed back to the |
|
454 * narrowed connection. |
|
455 * <br> |
|
456 * If however, the JMX client directly invoked the MBean from a higher |
|
457 * name space, without having narrowed to that name space first, then |
|
458 * the names that might be returned by that MBean will not be directly |
|
459 * usable - the JMX client will need to either |
|
460 * <a href="#ChangeTo">narrow to the name space</a> before using the |
|
461 * returned names, or convert the names to the higher level name space |
|
462 * context. |
|
463 * <br> |
|
464 * The {@link javax.management.namespace.JMXNamespaces JMXNamespaces} |
|
465 * class provides methods that can be used to perform that conversion. |
|
466 * </p> |
|
467 * |
|
468 * <h3 id="NamespacesAndNotifications">Name Spaces And Notifications</h3> |
|
469 * <p> |
|
470 * As <a href="#WhatIs">already explained</a>, name spaces are very |
|
471 * similar to {@code MBeanServer}s. It is thus possible to get |
|
472 * {@link javax.management.MBeanServerNotification MBeanServerNotifications} |
|
473 * when MBeans are added or removed within a name space, by registering |
|
474 * with the {@link javax.management.MBeanServerDelegate |
|
475 * MBeanServerDelegate} MBean of the corresponding name space.<br> |
|
476 * However, it must be noted that the notifications emitted by a |
|
477 * name space must be interpreted in the context of that name space. |
|
478 * For instance, if an MBean {@code "domain:type=Thing"} contained in |
|
479 * namespace "foo//bar" emits a notification, the source of the |
|
480 * notification will be {@code "domain:type=Thing"}, not |
|
481 * {@code "foo//bar//domain:type=Thing"}. <br> |
|
482 * It is therefore recommended to keep track of the name space |
|
483 * information when registering a listener with an MBean contained in |
|
484 * a name space, especially if the same listener is used to receive |
|
485 * notifications from different name spaces. An easy solution is to |
|
486 * use the handback, as illustrated in the code below. |
|
487 * <pre> |
|
488 * final MBeanServer server = ...; |
|
489 * final NotificationListener listener = new NotificationListener() { |
|
490 * public void handleNotification(Notification n, Object handback) { |
|
491 * if (!(n instanceof MBeanServerNotification)) { |
|
492 * System.err.println("Error: expected MBeanServerNotification"); |
|
493 * return; |
|
494 * } |
|
495 * final MBeanServerNotification mbsn = |
|
496 * (MBeanServerNotification) n; |
|
497 * |
|
498 * // We will pass the namespace path in the handback. |
|
499 * // |
|
500 * // The received notification must be interpreted in |
|
501 * // the context of its source - therefore |
|
502 * // mbsn.getMBeanName() does not include the name space |
|
503 * // path... |
|
504 * // |
|
505 * final String namespace = (String) handback; |
|
506 * System.out.println("Received " + mbsn.getType() + |
|
507 * " for MBean " + mbsn.getMBeanName() + |
|
508 * " from name space " + namespace); |
|
509 * } |
|
510 * }; |
|
511 * server.addNotificationListener(JMXNamespaces.insertPath("foo//bar", |
|
512 * MBeanServerDelegate.DELEGATE_NAME),listener,null,"foo//bar"); |
|
513 * server.addNotificationListener(JMXNamespaces.insertPath("foo//joe", |
|
514 * MBeanServerDelegate.DELEGATE_NAME),listener,null,"foo//joe"); |
|
515 * </pre> |
|
516 * </p> |
|
517 * <p> |
|
518 * JMX Connectors may require some configuration in order to be able |
|
519 * to forward notifications from MBeans located in name spaces. |
|
520 * The RMI JMX Connector Server |
|
521 * in the Java SE 7 platform is configured by default to internally |
|
522 * use the new {@linkplain javax.management.event event service} on |
|
523 * the server side. |
|
524 * When the connector server is configured in this way, JMX clients |
|
525 * which use the old JMX Notifications mechanism (such as clients |
|
526 * running on prior versions of the JDK) will be able to |
|
527 * to receive notifications from MBeans located in sub name spaces. |
|
528 * This is because the connector server will transparently delegate |
|
529 * their subscriptions to the underlying {@linkplain |
|
530 * javax.management.event event service}. In summary: |
|
531 * <ul> |
|
532 * <li> |
|
533 * On the server side: When exporting an {@code MBeanServer} |
|
534 * through a JMX Connector, you will need to make sure that the |
|
535 * connector server uses the new {@linkplain javax.management.event |
|
536 * event service} in order to register for notifications. If the |
|
537 * connector server doesn't use the event service, only clients |
|
538 * which explicitly use the new {@linkplain javax.management.event |
|
539 * event service} will be able to register for notifications |
|
540 * with MBeans located in sub name spaces. |
|
541 * </li> |
|
542 * <li> |
|
543 * On the client side: if the JMX Connector server (on the remote |
|
544 * server side) was configured to internally use the new |
|
545 * {@linkplain javax.management.event |
|
546 * event service}, then clients can continue to use the old |
|
547 * {@code MBeanServerConnection} add / remove notification |
|
548 * listener methods transparently. Otherwise, only clients which |
|
549 * explicitly use the new {@linkplain javax.management.event |
|
550 * event service} will be able to receive notifications from |
|
551 * MBeans contained in sub name spaces. |
|
552 * </li> |
|
553 * </ul> |
|
554 * </p> |
|
555 * <p> |
|
556 * These configuration issues apply at each node in the name space path, |
|
557 * whenever the name space points to a remote server. The |
|
558 * {@link javax.management.namespace.JMXRemoteNamespace |
|
559 * JMXRemoteNamespace} can be configured in such a way that it will |
|
560 * explicitly use an {@link javax.management.event.EventClient EventClient} |
|
561 * when forwarding subscription to the remote side. Note that this can be |
|
562 * unnecessary (and a waste of resources) if the underlying JMXConnector |
|
563 * returned by the JMXConnectorFactory (client side) already uses the |
|
564 * {@linkplain javax.management.event event service} to register for |
|
565 * notifications with the server side. |
|
566 * </p> |
|
567 * |
|
568 * <h3 id="Security">Name Spaces And Access Control</h3> |
|
569 * <p> |
|
570 * Access to MBeans exposed through JMX namespaces is controlled by |
|
571 * {@linkplain javax.management.namespace.JMXNamespacePermission |
|
572 * jmx namespace permissions}. These permissions are checked by the |
|
573 * MBeanServer in which the {@link |
|
574 * javax.management.namespace.JMXNamespace JMXNamespace} MBean is registered. |
|
575 * This is <a href="JMXNamespace.html#PermissionChecks">described in |
|
576 * details</a> in the {@link |
|
577 * javax.management.namespace.JMXNamespace JMXNamespace} class. |
|
578 * </p> |
|
579 * <p> |
|
580 * To implement a "firewall-like" access control in a JMX agent you |
|
581 * can also place an {@link |
|
582 * javax.management.remote.MBeanServerForwarder} in the JMX Connector |
|
583 * Server which exposes the top-level MBeanServer of your application. |
|
584 * This {@code MBeanServerForwarder} will be able to perform |
|
585 * authorization checks for all MBeans, including those located in |
|
586 * sub name spaces. |
|
587 * </p> |
|
588 * <p> |
|
589 * For a tighter access control we recommend using a {@link |
|
590 * java.lang.SecurityManager security manager}. |
|
591 * </p> |
|
592 * @since 1.7 |
|
593 * <p></p> |
|
594 **/ |
|
595 |
|
596 package javax.management.namespace; |
|
597 |