blob: 1095897d99b4536f0121d2c4c687dd526fb48775 [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 1999-2006 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
26package com.sun.jmx.mbeanserver;
27
28import java.util.Iterator;
29import java.util.logging.Level;
30import java.util.Set;
31import java.io.ObjectInputStream;
32import java.security.AccessController;
33import java.security.Permission;
34import java.security.PrivilegedExceptionAction;
35
36// RI import
37import javax.management.MBeanPermission;
38import javax.management.AttributeNotFoundException;
39import javax.management.MBeanException;
40import javax.management.ReflectionException;
41import javax.management.MBeanInfo;
42import javax.management.QueryExp;
43import javax.management.NotificationListener;
44import javax.management.NotificationFilter;
45import javax.management.ListenerNotFoundException;
46import javax.management.IntrospectionException;
47import javax.management.OperationsException;
48import javax.management.InstanceNotFoundException;
49import javax.management.NotCompliantMBeanException;
50import javax.management.MBeanRegistrationException;
51import javax.management.InstanceAlreadyExistsException;
52import javax.management.InvalidAttributeValueException;
53import javax.management.ObjectName;
54import javax.management.ObjectInstance;
55import javax.management.Attribute;
56import javax.management.AttributeList;
57import javax.management.RuntimeOperationsException;
58import javax.management.MBeanServer;
59import javax.management.MBeanServerDelegate;
60import javax.management.loading.ClassLoaderRepository;
61
62import static com.sun.jmx.defaults.JmxProperties.MBEANSERVER_LOGGER;
63import com.sun.jmx.interceptor.DefaultMBeanServerInterceptor;
64import com.sun.jmx.interceptor.MBeanServerInterceptor;
65
66/**
67 * This is the base class for MBean manipulation on the agent side. It
68 * contains the methods necessary for the creation, registration, and
69 * deletion of MBeans as well as the access methods for registered MBeans.
70 * This is the core component of the JMX infrastructure.
71 * <P>
72 * Every MBean which is added to the MBean server becomes manageable:
73 * its attributes and operations become remotely accessible through
74 * the connectors/adaptors connected to that MBean server.
75 * A Java object cannot be registered in the MBean server unless it is a
76 * JMX compliant MBean.
77 * <P>
78 * When an MBean is registered or unregistered in the MBean server an
79 * {@link javax.management.MBeanServerNotification MBeanServerNotification}
80 * Notification is emitted. To register an object as listener to
81 * MBeanServerNotifications you should call the MBean server method
82 * {@link #addNotificationListener addNotificationListener} with
83 * the <CODE>ObjectName</CODE> of the
84 * {@link javax.management.MBeanServerDelegate MBeanServerDelegate}.
85 * This <CODE>ObjectName</CODE> is:
86 * <BR>
87 * <CODE>JMImplementation:type=MBeanServerDelegate</CODE>.
88 *
89 * @since 1.5
90 */
91public final class JmxMBeanServer
92 implements SunJmxMBeanServer {
93
94 /** Control the default locking policy of the repository.
95 * By default, we will be using a fair locking policy.
96 **/
97 public static final boolean DEFAULT_FAIR_LOCK_POLICY = true;
98
99 private final MBeanInstantiator instantiator;
100 private final SecureClassLoaderRepository secureClr;
101
102 /** true if interceptors are enabled **/
103 private final boolean interceptorsEnabled;
104
105 /** Revisit: transient ??? **/
106 private final transient MBeanServer outerShell;
107
108 /** Revisit: transient ??? **/
109 private transient MBeanServerInterceptor mbsInterceptor = null;
110
111 /** Revisit: transient ??? **/
112 /** The MBeanServerDelegate object representing the MBean Server */
113 private final transient MBeanServerDelegate mBeanServerDelegateObject;
114
115 /**
116 * <b>Package:</b> Creates an MBeanServer with the
117 * specified default domain name, outer interface, and delegate.
118 * <p>The default domain name is used as the domain part in the ObjectName
119 * of MBeans if no domain is specified by the user.
120 * <ul><b>Note:</b>Using this constructor directly is strongly
121 * discouraged. You should use
122 * {@link javax.management.MBeanServerFactory#createMBeanServer(java.lang.String)}
123 * or
124 * {@link javax.management.MBeanServerFactory#newMBeanServer(java.lang.String)}
125 * instead.
126 * <p>
127 * By default, {@link MBeanServerInterceptor} are disabled. Use
128 * {@link #JmxMBeanServer(java.lang.String,javax.management.MBeanServer,javax.management.MBeanServerDelegate,boolean)} to enable them.
129 * </ul>
130 * @param domain The default domain name used by this MBeanServer.
131 * @param outer A pointer to the MBeanServer object that must be
132 * passed to the MBeans when invoking their
133 * {@link javax.management.MBeanRegistration} interface.
134 * @param delegate A pointer to the MBeanServerDelegate associated
135 * with the new MBeanServer. The new MBeanServer must register
136 * this MBean in its MBean repository.
137 * @exception IllegalArgumentException if the instantiator is null.
138 */
139 JmxMBeanServer(String domain, MBeanServer outer,
140 MBeanServerDelegate delegate) {
141 this(domain,outer,delegate,null,false);
142 }
143
144 /**
145 * <b>Package:</b> Creates an MBeanServer with the
146 * specified default domain name, outer interface, and delegate.
147 * <p>The default domain name is used as the domain part in the ObjectName
148 * of MBeans if no domain is specified by the user.
149 * <ul><b>Note:</b>Using this constructor directly is strongly
150 * discouraged. You should use
151 * {@link javax.management.MBeanServerFactory#createMBeanServer(java.lang.String)}
152 * or
153 * {@link javax.management.MBeanServerFactory#newMBeanServer(java.lang.String)}
154 * instead.
155 * </ul>
156 * @param domain The default domain name used by this MBeanServer.
157 * @param outer A pointer to the MBeanServer object that must be
158 * passed to the MBeans when invoking their
159 * {@link javax.management.MBeanRegistration} interface.
160 * @param delegate A pointer to the MBeanServerDelegate associated
161 * with the new MBeanServer. The new MBeanServer must register
162 * this MBean in its MBean repository.
163 * @param interceptors If <code>true</code>,
164 * {@link MBeanServerInterceptor} will be enabled (default is
165 * <code>false</code>)
166 * Note: this parameter is not taken into account by this
167 * implementation - the default value <code>false</code> is
168 * always used.
169 * @exception IllegalArgumentException if the instantiator is null.
170 */
171 JmxMBeanServer(String domain, MBeanServer outer,
172 MBeanServerDelegate delegate, boolean interceptors) {
173 this(domain,outer,delegate,null,false);
174 }
175
176 /**
177 * <b>Package:</b> Creates an MBeanServer.
178 * @param domain The default domain name used by this MBeanServer.
179 * @param outer A pointer to the MBeanServer object that must be
180 * passed to the MBeans when invoking their
181 * {@link javax.management.MBeanRegistration} interface.
182 * @param delegate A pointer to the MBeanServerDelegate associated
183 * with the new MBeanServer. The new MBeanServer must register
184 * this MBean in its MBean repository.
185 * @param instantiator The MBeanInstantiator that will be used to
186 * instantiate MBeans and take care of class loading issues.
187 * @param metadata The MetaData object that will be used by the
188 * MBean server in order to invoke the MBean interface of
189 * the registered MBeans.
190 * @param interceptors If <code>true</code>,
191 * {@link MBeanServerInterceptor} will be enabled (default is
192 * <code>false</code>).
193 */
194 JmxMBeanServer(String domain, MBeanServer outer,
195 MBeanServerDelegate delegate,
196 MBeanInstantiator instantiator,
197 boolean interceptors) {
198 this(domain,outer,delegate,instantiator,interceptors,true);
199 }
200
201 /**
202 * <b>Package:</b> Creates an MBeanServer.
203 * @param domain The default domain name used by this MBeanServer.
204 * @param outer A pointer to the MBeanServer object that must be
205 * passed to the MBeans when invoking their
206 * {@link javax.management.MBeanRegistration} interface.
207 * @param delegate A pointer to the MBeanServerDelegate associated
208 * with the new MBeanServer. The new MBeanServer must register
209 * this MBean in its MBean repository.
210 * @param instantiator The MBeanInstantiator that will be used to
211 * instantiate MBeans and take care of class loading issues.
212 * @param metadata The MetaData object that will be used by the
213 * MBean server in order to invoke the MBean interface of
214 * the registered MBeans.
215 * @param interceptors If <code>true</code>,
216 * {@link MBeanServerInterceptor} will be enabled (default is
217 * <code>false</code>).
218 * @param fairLock If {@code true}, the MBean repository will use a {@link
219 * java.util.concurrent.locks.ReentrantReadWriteLock#ReentrantReadWriteLock(boolean)
220 * fair locking} policy.
221 */
222 JmxMBeanServer(String domain, MBeanServer outer,
223 MBeanServerDelegate delegate,
224 MBeanInstantiator instantiator,
225 boolean interceptors,
226 boolean fairLock) {
227
228 if (instantiator == null) {
229 final ModifiableClassLoaderRepository
230 clr = new ClassLoaderRepositorySupport();
231 instantiator = new MBeanInstantiator(clr);
232 }
233 this.secureClr = new
234 SecureClassLoaderRepository(instantiator.getClassLoaderRepository());
235 if (delegate == null)
236 delegate = new MBeanServerDelegateImpl();
237 if (outer == null)
238 outer = this;
239
240 this.instantiator = instantiator;
241 this.mBeanServerDelegateObject = delegate;
242 this.outerShell = outer;
243
244 final Repository repository = new Repository(domain,fairLock);
245 this.mbsInterceptor =
246 new DefaultMBeanServerInterceptor(outer, delegate, instantiator,
247 repository);
248 this.interceptorsEnabled = interceptors;
249 initialize();
250 }
251
252 /**
253 * Tell whether {@link MBeanServerInterceptor}s are enabled on this
254 * object.
255 * @return <code>true</code> if {@link MBeanServerInterceptor}s are
256 * enabled.
257 * @see #newMBeanServer(java.lang.String,javax.management.MBeanServer,javax.management.MBeanServerDelegate,boolean)
258 **/
259 public boolean interceptorsEnabled() {
260 return interceptorsEnabled;
261 }
262
263 /**
264 * Return the MBeanInstantiator associated to this MBeanServer.
265 * @exception UnsupportedOperationException if
266 * {@link MBeanServerInterceptor}s
267 * are not enabled on this object.
268 * @see #interceptorsEnabled
269 **/
270 public MBeanInstantiator getMBeanInstantiator() {
271 if (interceptorsEnabled) return instantiator;
272 else throw new UnsupportedOperationException(
273 "MBeanServerInterceptors are disabled.");
274 }
275
276 /**
277 * Instantiates and registers an MBean in the MBean server.
278 * The MBean server will use its
279 * {@link javax.management.loading.ClassLoaderRepository Default Loader Repository}
280 * to load the class of the MBean.
281 * An object name is associated to the MBean.
282 * If the object name given is null, the MBean can automatically
283 * provide its own name by implementing the
284 * {@link javax.management.MBeanRegistration MBeanRegistration} interface.
285 * The call returns an <CODE>ObjectInstance</CODE> object representing
286 * the newly created MBean.
287 *
288 * @param className The class name of the MBean to be instantiated.
289 * @param name The object name of the MBean. May be null.
290 *
291 * @return An <CODE>ObjectInstance</CODE>, containing the
292 * <CODE>ObjectName</CODE> and the Java class name of the newly
293 * instantiated MBean.
294 *
295 * @exception ReflectionException Wraps an
296 * <CODE>{@link java.lang.ClassNotFoundException}</CODE> or an
297 * <CODE>{@link java.lang.Exception}</CODE> that occurred
298 * when trying to invoke the MBean's constructor.
299 * @exception InstanceAlreadyExistsException The MBean is already
300 * under the control of the MBean server.
301 * @exception MBeanRegistrationException The <CODE>preRegister()</CODE>
302 * (<CODE>MBeanRegistration</CODE> interface) method of the MBean
303 * has thrown an exception. The MBean will not be registered.
304 * @exception MBeanException The constructor of the MBean has thrown
305 * an exception.
306 * @exception NotCompliantMBeanException This class is not a JMX
307 * compliant MBean.
308 * @exception RuntimeOperationsException Wraps an
309 * <CODE>{@link java.lang.IllegalArgumentException}</CODE>:
310 * The className passed in parameter is null, the
311 * <CODE>ObjectName</CODE> passed in parameter contains a pattern
312 * or no <CODE>ObjectName</CODE> is specified for the MBean.
313 *
314 */
315 public ObjectInstance createMBean(String className, ObjectName name)
316 throws ReflectionException, InstanceAlreadyExistsException,
317 MBeanRegistrationException, MBeanException,
318 NotCompliantMBeanException {
319
320 return mbsInterceptor.createMBean(className,
321 cloneObjectName(name),
322 (Object[]) null,
323 (String[]) null);
324 }
325
326 /**
327 * Instantiates and registers an MBean in the MBean server.
328 * The class loader to be used is identified by its object name.
329 * An object name is associated to the MBean.
330 * If the object name of the loader is null, the ClassLoader that
331 * loaded the MBean server will be used.
332 * If the MBean's object name given is null, the MBean can
333 * automatically provide its own name by implementing the
334 * {@link javax.management.MBeanRegistration MBeanRegistration} interface.
335 * The call returns an <CODE>ObjectInstance</CODE> object representing
336 * the newly created MBean.
337 *
338 * @param className The class name of the MBean to be instantiated.
339 * @param name The object name of the MBean. May be null.
340 * @param loaderName The object name of the class loader to be used.
341 *
342 * @return An <CODE>ObjectInstance</CODE>, containing the
343 * <CODE>ObjectName</CODE> and the Java class name
344 * of the newly instantiated MBean.
345 *
346 * @exception ReflectionException Wraps an
347 * <CODE>{@link java.lang.ClassNotFoundException}</CODE> or an
348 * <CODE>{@link java.lang.Exception}</CODE> that occurred when trying
349 * to invoke the MBean's constructor.
350 * @exception InstanceAlreadyExistsException The MBean is already
351 * under the control of the MBean server.
352 * @exception MBeanRegistrationException The <CODE>preRegister()</CODE>
353 * (<CODE>MBeanRegistration</CODE> interface) method of the MBean
354 * has thrown an exception. The MBean will not be registered.
355 * @exception MBeanException The constructor of the MBean has thrown
356 * an exception
357 * @exception NotCompliantMBeanException This class is not a JMX
358 * compliant MBean.
359 * @exception InstanceNotFoundException The specified class loader
360 * is not registered in the MBean server.
361 * @exception RuntimeOperationsException Wraps an
362 * <CODE>{@link java.lang.IllegalArgumentException}</CODE>: The
363 * className passed in parameter is null, the <CODE>ObjectName</CODE>
364 * passed in parameter contains a pattern or no
365 * <CODE>ObjectName</CODE> is specified for the MBean.
366 */
367 public ObjectInstance createMBean(String className, ObjectName name,
368 ObjectName loaderName)
369 throws ReflectionException, InstanceAlreadyExistsException,
370 MBeanRegistrationException, MBeanException,
371 NotCompliantMBeanException, InstanceNotFoundException {
372
373 return mbsInterceptor.createMBean(className,
374 cloneObjectName(name),
375 loaderName,
376 (Object[]) null,
377 (String[]) null);
378 }
379
380 /**
381 * Instantiates and registers an MBean in the MBean server.
382 * The MBean server will use its
383 * {@link javax.management.loading.ClassLoaderRepository Default Loader Repository}
384 * to load the class of the MBean.
385 * An object name is associated to the MBean.
386 * If the object name given is null, the MBean can automatically
387 * provide its own name by implementing the
388 * {@link javax.management.MBeanRegistration MBeanRegistration} interface.
389 * The call returns an <CODE>ObjectInstance</CODE> object representing
390 * the newly created MBean.
391 *
392 * @param className The class name of the MBean to be instantiated.
393 * @param name The object name of the MBean. May be null.
394 * @param params An array containing the parameters of the constructor
395 * to be invoked.
396 * @param signature An array containing the signature of the
397 * constructor to be invoked.
398 *
399 * @return An <CODE>ObjectInstance</CODE>, containing the
400 * <CODE>ObjectName</CODE> and the Java class name
401 * of the newly instantiated MBean.
402 *
403 * @exception ReflectionException Wraps a
404 * <CODE>{@link java.lang.ClassNotFoundException}</CODE> or an
405 * <CODE>{@link java.lang.Exception}</CODE> that occurred
406 * when trying to invoke the MBean's constructor.
407 * @exception InstanceAlreadyExistsException The MBean is already
408 * under the control of the MBean server.
409 * @exception MBeanRegistrationException The <CODE>preRegister()</CODE>
410 * (<CODE>MBeanRegistration</CODE> interface) method of the MBean
411 * has thrown an exception. The MBean will not be registered.
412 * @exception MBeanException The constructor of the MBean has
413 * thrown an exception.
414 * @exception RuntimeOperationsException Wraps an
415 * <CODE>{@link java.lang.IllegalArgumentException}</CODE>: The
416 * className passed in parameter is null, the <CODE>ObjectName</CODE>
417 * passed in parameter contains a pattern or no
418 * <CODE>ObjectName</CODE> is specified for the MBean.
419 *
420 */
421 public ObjectInstance createMBean(String className, ObjectName name,
422 Object params[], String signature[])
423 throws ReflectionException, InstanceAlreadyExistsException,
424 MBeanRegistrationException, MBeanException,
425 NotCompliantMBeanException {
426
427 return mbsInterceptor.createMBean(className, cloneObjectName(name),
428 params, signature);
429 }
430
431 /**
432 * Instantiates and registers an MBean in the MBean server.
433 * The class loader to be used is identified by its object name.
434 * An object name is associated to the MBean. If the object name
435 * of the loader is not specified, the ClassLoader that loaded the
436 * MBean server will be used.
437 * If the MBean object name given is null, the MBean can automatically
438 * provide its own name by implementing the
439 * {@link javax.management.MBeanRegistration MBeanRegistration} interface.
440 * The call returns an <CODE>ObjectInstance</CODE> object representing
441 * the newly created MBean.
442 *
443 * @param className The class name of the MBean to be instantiated.
444 * @param name The object name of the MBean. May be null.
445 * @param params An array containing the parameters of the constructor
446 * to be invoked.
447 * @param signature An array containing the signature of the
448 * constructor to be invoked.
449 * @param loaderName The object name of the class loader to be used.
450 *
451 * @return An <CODE>ObjectInstance</CODE>, containing the
452 * <CODE>ObjectName</CODE> and the Java class name of the newly
453 * instantiated MBean.
454 *
455 * @exception ReflectionException Wraps a
456 * <CODE>{@link java.lang.ClassNotFoundException}</CODE> or an
457 * <CODE>{@link java.lang.Exception}</CODE>
458 * that occurred when trying to invoke the MBean's constructor.
459 * @exception InstanceAlreadyExistsException The MBean is already
460 * under the control of the MBean server.
461 * @exception MBeanRegistrationException The <CODE>preRegister()</CODE>
462 * (<CODE>MBeanRegistration</CODE> interface) method of the MBean
463 * has thrown an exception. The MBean will not be registered.
464 * @exception MBeanException The constructor of the MBean has
465 * thrown an exception
466 * @exception InstanceNotFoundException The specified class loader is
467 * not registered in the MBean server.
468 * @exception RuntimeOperationsException Wraps an
469 * <CODE>{@link java.lang.IllegalArgumentException}</CODE>: The
470 * className passed in parameter is null, the <CODE>ObjectName</CODE>
471 * passed in parameter contains a pattern or no
472 * <CODE>ObjectName</CODE> is specified for the MBean.
473 *
474 */
475 public ObjectInstance createMBean(String className, ObjectName name,
476 ObjectName loaderName, Object params[],
477 String signature[])
478 throws ReflectionException, InstanceAlreadyExistsException,
479 MBeanRegistrationException, MBeanException,
480 NotCompliantMBeanException, InstanceNotFoundException {
481
482 return mbsInterceptor.createMBean(className, cloneObjectName(name),
483 loaderName, params, signature);
484 }
485
486 /**
487 * Registers a pre-existing object as an MBean with the MBean server.
488 * If the object name given is null, the MBean may automatically
489 * provide its own name by implementing the
490 * {@link javax.management.MBeanRegistration MBeanRegistration} interface.
491 * The call returns an <CODE>ObjectInstance</CODE> object representing
492 * the registered MBean.
493 *
494 * @param object The MBean to be registered as an MBean.
495 * @param name The object name of the MBean. May be null.
496 *
497 * @return The <CODE>ObjectInstance</CODE> for the MBean that has been
498 * registered.
499 *
500 * @exception InstanceAlreadyExistsException The MBean is already
501 * under the control of the MBean server.
502 * @exception MBeanRegistrationException The <CODE>preRegister()</CODE>
503 * (<CODE>MBeanRegistration</CODE> interface) method of the MBean
504 * has thrown an exception. The MBean will not be registered.
505 * @exception NotCompliantMBeanException This object is not a JMX
506 * compliant MBean
507 * @exception RuntimeOperationsException Wraps an
508 * <CODE>{@link java.lang.IllegalArgumentException}</CODE>: The
509 * object passed in parameter is null or no object name is specified.
510 *
511 */
512 public ObjectInstance registerMBean(Object object, ObjectName name)
513 throws InstanceAlreadyExistsException, MBeanRegistrationException,
514 NotCompliantMBeanException {
515
516 return mbsInterceptor.registerMBean(object, cloneObjectName(name));
517 }
518
519 /**
520 * De-registers an MBean from the MBean server. The MBean is identified by
521 * its object name. Once the method has been invoked, the MBean may
522 * no longer be accessed by its object name.
523 *
524 * @param name The object name of the MBean to be de-registered.
525 *
526 * @exception InstanceNotFoundException The MBean specified is not
527 * registered in the MBean server.
528 * @exception MBeanRegistrationException The <code>preDeregister()</code>
529 * (<CODE>MBeanRegistration</CODE> interface) method of the MBean
530 * has thrown an exception.
531 * @exception RuntimeOperationsException Wraps an
532 * <CODE>{@link java.lang.IllegalArgumentException}</CODE>: The
533 * object name in parameter is null or the MBean you are when
534 * trying to de-register is the
535 * {@link javax.management.MBeanServerDelegate MBeanServerDelegate}
536 * MBean.
537 **/
538 public void unregisterMBean(ObjectName name)
539 throws InstanceNotFoundException, MBeanRegistrationException {
540 mbsInterceptor.unregisterMBean(cloneObjectName(name));
541 }
542
543 /**
544 * Gets the <CODE>ObjectInstance</CODE> for a given MBean registered
545 * with the MBean server.
546 *
547 * @param name The object name of the MBean.
548 *
549 * @return The <CODE>ObjectInstance</CODE> associated to the MBean
550 * specified by <VAR>name</VAR>.
551 *
552 * @exception InstanceNotFoundException The MBean specified is not
553 * registered in the MBean server.
554 */
555 public ObjectInstance getObjectInstance(ObjectName name)
556 throws InstanceNotFoundException {
557
558 return mbsInterceptor.getObjectInstance(cloneObjectName(name));
559 }
560
561 /**
562 * Gets MBeans controlled by the MBean server. This method allows any
563 * of the following to be obtained: All MBeans, a set of MBeans specified
564 * by pattern matching on the <CODE>ObjectName</CODE> and/or a Query
565 * expression, a specific MBean. When the object name is null or no
566 * domain and key properties are specified, all objects are to be
567 * selected (and filtered if a query is specified). It returns the
568 * set of <CODE>ObjectInstance</CODE> objects (containing the
569 * <CODE>ObjectName</CODE> and the Java Class name) for
570 * the selected MBeans.
571 *
572 * @param name The object name pattern identifying the MBeans to
573 * be retrieved. If null or or no domain and key properties
574 * are specified, all the MBeans registered will be retrieved.
575 * @param query The query expression to be applied for selecting
576 * MBeans. If null no query expression will be applied for
577 * selecting MBeans.
578 *
579 * @return A set containing the <CODE>ObjectInstance</CODE> objects
580 * for the selected MBeans.
581 * If no MBean satisfies the query an empty list is returned.
582 *
583 */
584 public Set<ObjectInstance> queryMBeans(ObjectName name, QueryExp query) {
585
586 return mbsInterceptor.queryMBeans(cloneObjectName(name), query);
587 }
588
589 /**
590 * Gets the names of MBeans controlled by the MBean server. This method
591 * enables any of the following to be obtained: The names of all MBeans,
592 * the names of a set of MBeans specified by pattern matching on the
593 * <CODE>ObjectName</CODE> and/or a Query expression, a specific
594 * MBean name (equivalent to testing whether an MBean is registered).
595 * When the object name is null or or no domain and key properties are
596 * specified, all objects are selected (and filtered if a query is
597 * specified). It returns the set of ObjectNames for the MBeans
598 * selected.
599 *
600 * @param name The object name pattern identifying the MBeans to be
601 * retrieved. If null or no domain and key properties are
602 * specified, all the MBeans registered will be retrieved.
603 * @param query The query expression to be applied for selecting
604 * MBeans. If null no query expression will be applied for
605 * selecting MBeans.
606 *
607 * @return A set containing the ObjectNames for the MBeans selected.
608 * If no MBean satisfies the query, an empty list is returned.
609 *
610 */
611 public Set<ObjectName> queryNames(ObjectName name, QueryExp query) {
612
613 return mbsInterceptor.queryNames(cloneObjectName(name), query);
614 }
615
616 /**
617 * Checks whether an MBean, identified by its object name, is already
618 * registered with the MBean server.
619 *
620 * @param name The object name of the MBean to be checked.
621 *
622 * @return True if the MBean is already registered in the MBean server,
623 * false otherwise.
624 *
625 * @exception RuntimeOperationsException Wraps an
626 * <CODE>{@link java.lang.IllegalArgumentException}</CODE>: The object
627 * name in parameter is null.
628 *
629 */
630 public boolean isRegistered(ObjectName name) {
631
632 return mbsInterceptor.isRegistered(name);
633 }
634
635 /**
636 * Returns the number of MBeans registered in the MBean server.
637 */
638 public Integer getMBeanCount() {
639
640 return mbsInterceptor.getMBeanCount();
641 }
642
643 /**
644 * Gets the value of a specific attribute of a named MBean. The MBean
645 * is identified by its object name.
646 *
647 * @param name The object name of the MBean from which the attribute
648 * is to be retrieved.
649 * @param attribute A String specifying the name of the attribute to be
650 * retrieved.
651 *
652 * @return The value of the retrieved attribute.
653 *
654 * @exception AttributeNotFoundException The attribute specified
655 * is not accessible in the MBean.
656 * @exception MBeanException Wraps an exception thrown by the
657 * MBean's getter.
658 * @exception InstanceNotFoundException The MBean specified is not
659 * registered in the MBean server.
660 * @exception ReflectionException Wraps an
661 * <CODE>{@link java.lang.Exception}</CODE> thrown when trying to
662 * invoke the setter.
663 * @exception RuntimeOperationsException Wraps an
664 * <CODE>{@link java.lang.IllegalArgumentException}</CODE>:
665 * The object name in parameter is null or the attribute in
666 * parameter is null.
667 */
668 public Object getAttribute(ObjectName name, String attribute)
669 throws MBeanException, AttributeNotFoundException,
670 InstanceNotFoundException, ReflectionException {
671
672 return mbsInterceptor.getAttribute(cloneObjectName(name), attribute);
673 }
674
675
676 /**
677 * Enables the values of several attributes of a named MBean. The MBean
678 * is identified by its object name.
679 *
680 * @param name The object name of the MBean from which the attributes are
681 * retrieved.
682 * @param attributes A list of the attributes to be retrieved.
683 *
684 * @return The list of the retrieved attributes.
685 *
686 * @exception InstanceNotFoundException The MBean specified is not
687 * registered in the MBean server.
688 * @exception ReflectionException An exception occurred when trying
689 * to invoke the getAttributes method of a Dynamic MBean.
690 * @exception RuntimeOperationsException Wrap an
691 * <CODE>{@link java.lang.IllegalArgumentException}</CODE>: The
692 * object name in parameter is null or attributes in parameter
693 * is null.
694 *
695 */
696 public AttributeList getAttributes(ObjectName name, String[] attributes)
697 throws InstanceNotFoundException, ReflectionException {
698
699 return mbsInterceptor.getAttributes(cloneObjectName(name), attributes);
700
701 }
702
703 /**
704 * Sets the value of a specific attribute of a named MBean. The MBean
705 * is identified by its object name.
706 *
707 * @param name The name of the MBean within which the attribute is
708 * to be set.
709 * @param attribute The identification of the attribute to be set
710 * and the value it is to be set to.
711 *
712 * @exception InstanceNotFoundException The MBean specified is
713 * not registered in the MBean server.
714 * @exception AttributeNotFoundException The attribute specified is
715 * not accessible in the MBean.
716 * @exception InvalidAttributeValueException The value specified for
717 * the attribute is not valid.
718 * @exception MBeanException Wraps an exception thrown by the
719 * MBean's setter.
720 * @exception ReflectionException Wraps an
721 * <CODE>{@link java.lang.Exception}</CODE> thrown when trying
722 * to invoke the setter.
723 * @exception RuntimeOperationsException Wraps an
724 * <CODE>{@link java.lang.IllegalArgumentException}</CODE>: The
725 * object name in parameter is null or the attribute in parameter
726 * is null.
727 */
728 public void setAttribute(ObjectName name, Attribute attribute)
729 throws InstanceNotFoundException, AttributeNotFoundException,
730 InvalidAttributeValueException, MBeanException,
731 ReflectionException {
732
733 mbsInterceptor.setAttribute(cloneObjectName(name),
734 cloneAttribute(attribute));
735 }
736
737 /**
738 * Sets the values of several attributes of a named MBean. The MBean is
739 * identified by its object name.
740 *
741 * @param name The object name of the MBean within which the
742 * attributes are to be set.
743 * @param attributes A list of attributes: The identification of the
744 * attributes to be set and the values they are to be set to.
745 *
746 * @return The list of attributes that were set, with their new values.
747 *
748 * @exception InstanceNotFoundException The MBean specified is not
749 * registered in the MBean server.
750 * @exception ReflectionException An exception occurred when trying
751 * to invoke the getAttributes method of a Dynamic MBean.
752 * @exception RuntimeOperationsException Wraps an
753 * <CODE>{@link java.lang.IllegalArgumentException}</CODE>:
754 * The object name in parameter is null or attributes in
755 * parameter is null.
756 *
757 */
758 public AttributeList setAttributes(ObjectName name,
759 AttributeList attributes)
760 throws InstanceNotFoundException, ReflectionException {
761
762 return mbsInterceptor.setAttributes(cloneObjectName(name),
763 cloneAttributeList(attributes));
764 }
765
766 /**
767 * Invokes an operation on an MBean.
768 *
769 * @param name The object name of the MBean on which the method is to be
770 * invoked.
771 * @param operationName The name of the operation to be invoked.
772 * @param params An array containing the parameters to be set when
773 * the operation is invoked
774 * @param signature An array containing the signature of the operation.
775 * The class objects will be loaded using the same class loader as
776 * the one used for loading the MBean on which the operation was
777 * invoked.
778 *
779 * @return The object returned by the operation, which represents the
780 * result ofinvoking the operation on the MBean specified.
781 *
782 * @exception InstanceNotFoundException The MBean specified is not
783 * registered in the MBean server.
784 * @exception MBeanException Wraps an exception thrown by the MBean's
785 * invoked method.
786 * @exception ReflectionException Wraps an
787 * <CODE>{@link java.lang.Exception}</CODE> thrown while trying
788 * to invoke the method.
789 *
790 */
791 public Object invoke(ObjectName name, String operationName,
792 Object params[], String signature[])
793 throws InstanceNotFoundException, MBeanException,
794 ReflectionException {
795 return mbsInterceptor.invoke(cloneObjectName(name), operationName,
796 params, signature);
797 }
798
799 /**
800 * Returns the default domain used for naming the MBean.
801 * The default domain name is used as the domain part in the ObjectName
802 * of MBeans if no domain is specified by the user.
803 */
804 public String getDefaultDomain() {
805 return mbsInterceptor.getDefaultDomain();
806 }
807
808 // From MBeanServer
809 public String[] getDomains() {
810 return mbsInterceptor.getDomains();
811 }
812
813 /**
814 * Adds a listener to a registered MBean.
815 *
816 * @param name The name of the MBean on which the listener should be added.
817 * @param listener The listener object which will handle the
818 * notifications emitted by the registered MBean.
819 * @param filter The filter object. If filter is null, no filtering
820 * will be performed before handling notifications.
821 * @param handback The context to be sent to the listener when a
822 * notification is emitted.
823 *
824 * @exception InstanceNotFoundException The MBean name provided does
825 * not match any of the registered MBeans.
826 */
827 public void addNotificationListener(ObjectName name,
828 NotificationListener listener,
829 NotificationFilter filter,
830 Object handback)
831 throws InstanceNotFoundException {
832
833 mbsInterceptor.addNotificationListener(cloneObjectName(name), listener,
834 filter, handback);
835 }
836
837 /**
838 * Adds a listener to a registered MBean.
839 *
840 * @param name The name of the MBean on which the listener should be added.
841 * @param listener The object name of the listener which will handle the
842 * notifications emitted by the registered MBean.
843 * @param filter The filter object. If filter is null, no filtering will
844 * be performed before handling notifications.
845 * @param handback The context to be sent to the listener when a
846 * notification is emitted.
847 *
848 * @exception InstanceNotFoundException The MBean name of the
849 * notification listener or of the notification broadcaster
850 * does not match any of the registered MBeans.
851 */
852 public void addNotificationListener(ObjectName name, ObjectName listener,
853 NotificationFilter filter, Object handback)
854 throws InstanceNotFoundException {
855
856 mbsInterceptor.addNotificationListener(cloneObjectName(name), listener,
857 filter, handback);
858 }
859
860 public void removeNotificationListener(ObjectName name,
861 NotificationListener listener)
862 throws InstanceNotFoundException, ListenerNotFoundException {
863
864 mbsInterceptor.removeNotificationListener(cloneObjectName(name),
865 listener);
866 }
867
868 public void removeNotificationListener(ObjectName name,
869 NotificationListener listener,
870 NotificationFilter filter,
871 Object handback)
872 throws InstanceNotFoundException, ListenerNotFoundException {
873
874 mbsInterceptor.removeNotificationListener(cloneObjectName(name),
875 listener, filter, handback);
876 }
877
878 public void removeNotificationListener(ObjectName name,
879 ObjectName listener)
880 throws InstanceNotFoundException, ListenerNotFoundException {
881
882 mbsInterceptor.removeNotificationListener(cloneObjectName(name),
883 listener);
884 }
885
886 public void removeNotificationListener(ObjectName name,
887 ObjectName listener,
888 NotificationFilter filter,
889 Object handback)
890 throws InstanceNotFoundException, ListenerNotFoundException {
891
892 mbsInterceptor.removeNotificationListener(cloneObjectName(name),
893 listener, filter, handback);
894 }
895
896 /**
897 * This method discovers the attributes and operations that an MBean exposes
898 * for management.
899 *
900 * @param name The name of the MBean to analyze
901 *
902 * @return An instance of <CODE>MBeanInfo</CODE> allowing the retrieval of
903 * all attributes and operations of this MBean.
904 *
905 * @exception IntrospectionException An exception occurs during
906 * introspection.
907 * @exception InstanceNotFoundException The MBean specified is not found.
908 * @exception ReflectionException An exception occurred when trying to
909 * invoke the getMBeanInfo of a Dynamic MBean.
910 */
911 public MBeanInfo getMBeanInfo(ObjectName name) throws
912 InstanceNotFoundException, IntrospectionException, ReflectionException {
913
914 return mbsInterceptor.getMBeanInfo(cloneObjectName(name));
915 }
916
917 /**
918 * Instantiates an object using the list of all class loaders registered
919 * in the MBean server (using its
920 * {@link javax.management.loading.ClassLoaderRepository Default Loader Repository}).
921 * The object's class should have a public constructor.
922 * It returns a reference to the newly created object.
923 * The newly created object is not registered in the MBean server.
924 *
925 * @param className The class name of the object to be instantiated.
926 *
927 * @return The newly instantiated object.
928 *
929 * @exception ReflectionException Wraps the
930 * <CODE>{@link java.lang.ClassNotFoundException}</CODE> or the
931 * <CODE>{@link java.lang.Exception}</CODE> that
932 * occurred when trying to invoke the object's constructor.
933 * @exception MBeanException The constructor of the object has thrown
934 * an exception.
935 * @exception RuntimeOperationsException Wraps an
936 * <CODE>{@link java.lang.IllegalArgumentException}</CODE>:
937 * The className passed in parameter is null.
938 *
939 */
940 public Object instantiate(String className)
941 throws ReflectionException, MBeanException {
942
943 /* Permission check */
944 checkMBeanPermission(className, null, null, "instantiate");
945
946 return instantiator.instantiate(className);
947 }
948
949 /**
950 * Instantiates an object using the class Loader specified by its
951 * <CODE>ObjectName</CODE>.
952 * If the loader name is null, the ClassLoader that loaded the
953 * MBean Server will be used.
954 * The object's class should have a public constructor.
955 * It returns a reference to the newly created object.
956 * The newly created object is not registered in the MBean server.
957 *
958 * @param className The class name of the MBean to be instantiated.
959 * @param loaderName The object name of the class loader to be used.
960 *
961 * @return The newly instantiated object.
962 *
963 * @exception ReflectionException Wraps the
964 * <CODE>{@link java.lang.ClassNotFoundException}</CODE> or the
965 * <CODE>{@link java.lang.Exception}</CODE> that
966 * occurred when trying to invoke the object's constructor.
967 * @exception MBeanException The constructor of the object has thrown
968 * an exception.
969 * @exception InstanceNotFoundException The specified class loader
970 * is not registered in the MBaenServer.
971 * @exception RuntimeOperationsException Wraps an
972 * <CODE>{@link java.lang.IllegalArgumentException}</CODE>: The
973 * className passed in parameter is null.
974 *
975 */
976 public Object instantiate(String className, ObjectName loaderName)
977 throws ReflectionException, MBeanException,
978 InstanceNotFoundException {
979
980 /* Permission check */
981 checkMBeanPermission(className, null, null, "instantiate");
982
983 ClassLoader myLoader = outerShell.getClass().getClassLoader();
984 return instantiator.instantiate(className, loaderName, myLoader);
985 }
986
987 /**
988 * Instantiates an object using the list of all class loaders registered
989 * in the MBean server (using its
990 * {@link javax.management.loading.ClassLoaderRepository Default Loader Repository}).
991 * The object's class should have a public constructor.
992 * The call returns a reference to the newly created object.
993 * The newly created object is not registered in the MBean server.
994 *
995 * @param className The class name of the object to be instantiated.
996 * @param params An array containing the parameters of the constructor
997 * to be invoked.
998 * @param signature An array containing the signature of the
999 * constructor to be invoked.
1000 *
1001 * @return The newly instantiated object.
1002 *
1003 * @exception ReflectionException Wraps the
1004 * <CODE>{@link java.lang.ClassNotFoundException}</CODE> or the
1005 * <CODE>{@link java.lang.Exception}</CODE> that
1006 * occurred when trying to invoke the object's constructor.
1007 * @exception MBeanException The constructor of the object has thrown
1008 * an exception.
1009 * @exception RuntimeOperationsException Wraps an
1010 * <CODE>{@link java.lang.IllegalArgumentException}</CODE>:
1011 * The className passed in parameter is null.
1012 *
1013 */
1014 public Object instantiate(String className, Object params[],
1015 String signature[])
1016 throws ReflectionException, MBeanException {
1017
1018 /* Permission check */
1019 checkMBeanPermission(className, null, null, "instantiate");
1020
1021 ClassLoader myLoader = outerShell.getClass().getClassLoader();
1022 return instantiator.instantiate(className, params, signature,
1023 myLoader);
1024 }
1025
1026 /**
1027 * Instantiates an object. The class loader to be used is identified
1028 * by its object name. If the object name of the loader is null,
1029 * the ClassLoader that loaded the MBean server will be used.
1030 * The object's class should have a public constructor.
1031 * The call returns a reference to the newly created object.
1032 * The newly created object is not registered in the MBean server.
1033 *
1034 * @param className The class name of the object to be instantiated.
1035 * @param params An array containing the parameters of the constructor
1036 * to be invoked.
1037 * @param signature An array containing the signature of the constructor
1038 * to be invoked.
1039 * @param loaderName The object name of the class loader to be used.
1040 *
1041 * @return The newly instantiated object.
1042 *
1043 * @exception ReflectionException Wraps the
1044 * <CODE>{@link java.lang.ClassNotFoundException}</CODE> or the
1045 * <CODE>{@link java.lang.Exception}</CODE> that
1046 * occurred when trying to invoke the object's constructor.
1047 * @exception MBeanException The constructor of the object has thrown
1048 * an exception.
1049 * @exception InstanceNotFoundException The specified class loader
1050 * is not registered in the MBean server.
1051 * @exception RuntimeOperationsException Wraps an
1052 * <CODE>{@link java.lang.IllegalArgumentException}</CODE>:
1053 * The className passed in parameter is null.
1054 *
1055 */
1056 public Object instantiate(String className, ObjectName loaderName,
1057 Object params[], String signature[])
1058 throws ReflectionException, MBeanException,
1059 InstanceNotFoundException {
1060
1061 /* Permission check */
1062 checkMBeanPermission(className, null, null, "instantiate");
1063
1064 ClassLoader myLoader = outerShell.getClass().getClassLoader();
1065 return instantiator.instantiate(className,loaderName,params,signature,
1066 myLoader);
1067 }
1068
1069 /**
1070 * Returns true if the MBean specified is an instance of the specified
1071 * class, false otherwise.
1072 *
1073 * @param name The <CODE>ObjectName</CODE> of the MBean.
1074 * @param className The name of the class.
1075 *
1076 * @return true if the MBean specified is an instance of the specified
1077 * class, false otherwise.
1078 *
1079 * @exception InstanceNotFoundException The MBean specified is not
1080 * registered in the MBean server.
1081 */
1082 public boolean isInstanceOf(ObjectName name, String className)
1083 throws InstanceNotFoundException {
1084
1085 return mbsInterceptor.isInstanceOf(cloneObjectName(name), className);
1086 }
1087
1088 /**
1089 * De-serializes a byte array in the context of the class loader
1090 * of an MBean.
1091 *
1092 * @param name The name of the MBean whose class loader should
1093 * be used for the de-serialization.
1094 * @param data The byte array to be de-sererialized.
1095 *
1096 * @return The de-serialized object stream.
1097 *
1098 * @exception InstanceNotFoundException The MBean specified is not
1099 * found.
1100 * @exception OperationsException Any of the usual Input/Output
1101 * related exceptions.
1102 *
1103 */
1104 @Deprecated
1105 public ObjectInputStream deserialize(ObjectName name, byte[] data)
1106 throws InstanceNotFoundException, OperationsException {
1107
1108 /* Permission check */
1109 // This call requires MBeanPermission 'getClassLoaderFor'
1110 final ClassLoader loader = getClassLoaderFor(name);
1111
1112 return instantiator.deserialize(loader, data);
1113 }
1114
1115 /**
1116 * De-serializes a byte array in the context of a given MBean class loader.
1117 * The class loader is the one that loaded the class with name "className".
1118 *
1119 * @param className The name of the class whose class loader should be
1120 * used for the de-serialization.
1121 * @param data The byte array to be de-sererialized.
1122 *
1123 * @return The de-serialized object stream.
1124 *
1125 * @exception OperationsException Any of the usual Input/Output
1126 * related exceptions.
1127 * @exception ReflectionException The specified class could not be
1128 * loaded by the default loader repository
1129 *
1130 */
1131 @Deprecated
1132 public ObjectInputStream deserialize(String className, byte[] data)
1133 throws OperationsException, ReflectionException {
1134
1135 if (className == null) {
1136 throw new RuntimeOperationsException(
1137 new IllegalArgumentException(),
1138 "Null className passed in parameter");
1139 }
1140
1141 /* Permission check */
1142 // This call requires MBeanPermission 'getClassLoaderRepository'
1143 final ClassLoaderRepository clr = getClassLoaderRepository();
1144
1145 Class theClass;
1146 try {
1147 if (clr == null) throw new ClassNotFoundException(className);
1148 theClass = clr.loadClass(className);
1149 } catch (ClassNotFoundException e) {
1150 throw new ReflectionException(e,
1151 "The given class could not be " +
1152 "loaded by the default loader " +
1153 "repository");
1154 }
1155
1156 return instantiator.deserialize(theClass.getClassLoader(), data);
1157 }
1158
1159 /**
1160 * De-serializes a byte array in the context of a given MBean class loader.
1161 * The class loader is the one that loaded the class with name "className".
1162 * The name of the class loader to be used for loading the specified
1163 * class is specified.
1164 * If null, the MBean Server's class loader will be used.
1165 *
1166 * @param className The name of the class whose class loader should be
1167 * used for the de-serialization.
1168 * @param data The byte array to be de-sererialized.
1169 * @param loaderName The name of the class loader to be used for
1170 * loading the specified class.
1171 * If null, the MBean Server's class loader will be used.
1172 *
1173 * @return The de-serialized object stream.
1174 *
1175 * @exception InstanceNotFoundException The specified class loader
1176 * MBean is not found.
1177 * @exception OperationsException Any of the usual Input/Output
1178 * related exceptions.
1179 * @exception ReflectionException The specified class could not
1180 * be loaded by the specified class loader.
1181 *
1182 */
1183 @Deprecated
1184 public ObjectInputStream deserialize(String className,
1185 ObjectName loaderName,
1186 byte[] data) throws
1187 InstanceNotFoundException, OperationsException, ReflectionException {
1188
1189 // Clone ObjectName
1190 //
1191 loaderName = cloneObjectName(loaderName);
1192
1193 /* Permission check */
1194 // Make this call just to force the 'getClassLoader'
1195 // permission check
1196 try {
1197 getClassLoader(loaderName);
1198 } catch (SecurityException e) {
1199 throw e;
1200 } catch (Exception e) {
1201 }
1202
1203 ClassLoader myLoader = outerShell.getClass().getClassLoader();
1204 return instantiator.deserialize(className, loaderName, data, myLoader);
1205 }
1206
1207 /**
1208 * Initializes this MBeanServer, registering the MBeanServerDelegate.
1209 * <p>This method must be called once, before using the MBeanServer.
1210 **/
1211 private void initialize() {
1212 if (instantiator == null) throw new
1213 IllegalStateException("instantiator must not be null.");
1214
1215 // Registers the MBeanServer identification MBean
1216 try {
1217 AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
1218 public Object run() throws Exception {
1219 mbsInterceptor.registerMBean(
1220 mBeanServerDelegateObject,
1221 MBeanServerDelegate.DELEGATE_NAME);
1222 return null;
1223 }
1224 });
1225 } catch (SecurityException e) {
1226 if (MBEANSERVER_LOGGER.isLoggable(Level.FINEST)) {
1227 MBEANSERVER_LOGGER.logp(Level.FINEST,
1228 JmxMBeanServer.class.getName(), "initialize",
1229 "Unexpected security exception occurred", e);
1230 }
1231 throw e;
1232 } catch (Exception e) {
1233 if (MBEANSERVER_LOGGER.isLoggable(Level.FINEST)) {
1234 MBEANSERVER_LOGGER.logp(Level.FINEST,
1235 JmxMBeanServer.class.getName(), "initialize",
1236 "Unexpected exception occurred", e);
1237 }
1238 throw new
1239 IllegalStateException("Can't register delegate.");
1240 }
1241
1242
1243 /* Add my class loader to the repository
1244 This can be null if my class loader is the bootstrap
1245 class loader. The ClassLoaderRepository knows how
1246 to handle that case. */
1247 ClassLoader myLoader = outerShell.getClass().getClassLoader();
1248 final ModifiableClassLoaderRepository loaders =
1249 instantiator.getClassLoaderRepository();
1250 if (loaders != null) {
1251 loaders.addClassLoader(myLoader);
1252
1253 /* Add the system class loader, so that if the MBean server is
1254 loaded by the bootstrap class loader we can still load
1255 MBeans from the classpath using
1256 createMBean(className, objectName).
1257
1258 If this class (JmxMBeanServer) was not loaded by the
1259 system class loader or a parent of it, then the caller
1260 must have RuntimePermission("getClassLoader") for the
1261 getSystemClassLoader() call to succeed. If the caller
1262 does not have that permission, any call to
1263 Class.getClassLoader() will fail. Since there are lots
1264 of those in JMX, we better throw the exception now.
1265
1266 This permission question is irrelevant when JMX is part
1267 of J2SE (as of 1.5). */
1268 ClassLoader systemLoader = ClassLoader.getSystemClassLoader();
1269 if (systemLoader != myLoader)
1270 loaders.addClassLoader(systemLoader);
1271 }
1272 }
1273
1274 /**
1275 * Return the MBeanServerInterceptor.
1276 * @exception UnsupportedOperationException if
1277 * {@link MBeanServerInterceptor}s
1278 * are not enabled on this object.
1279 * @see #interceptorsEnabled
1280 **/
1281 public synchronized MBeanServerInterceptor getMBeanServerInterceptor() {
1282 if (interceptorsEnabled) return mbsInterceptor;
1283 else throw new UnsupportedOperationException(
1284 "MBeanServerInterceptors are disabled.");
1285 }
1286
1287 /**
1288 * Set the MBeanServerInterceptor.
1289 * @exception UnsupportedOperationException if
1290 * {@link MBeanServerInterceptor}s
1291 * are not enabled on this object.
1292 * @see #interceptorsEnabled
1293 **/
1294 public synchronized void
1295 setMBeanServerInterceptor(MBeanServerInterceptor interceptor) {
1296 if (!interceptorsEnabled) throw new UnsupportedOperationException(
1297 "MBeanServerInterceptors are disabled.");
1298 if (interceptor == null) throw new
1299 IllegalArgumentException("MBeanServerInterceptor is null");
1300 mbsInterceptor = interceptor;
1301 }
1302
1303 /**
1304 * <p>Return the {@link java.lang.ClassLoader} that was used for
1305 * loading the class of the named MBean.
1306 * @param mbeanName The ObjectName of the MBean.
1307 * @return The ClassLoader used for that MBean.
1308 * @exception InstanceNotFoundException if the named MBean is not found.
1309 */
1310 public ClassLoader getClassLoaderFor(ObjectName mbeanName)
1311 throws InstanceNotFoundException {
1312 return mbsInterceptor.getClassLoaderFor(cloneObjectName(mbeanName));
1313 }
1314
1315 /**
1316 * <p>Return the named {@link java.lang.ClassLoader}.
1317 * @param loaderName The ObjectName of the ClassLoader.
1318 * @return The named ClassLoader.
1319 * @exception InstanceNotFoundException if the named ClassLoader
1320 * is not found.
1321 */
1322 public ClassLoader getClassLoader(ObjectName loaderName)
1323 throws InstanceNotFoundException {
1324 return mbsInterceptor.getClassLoader(cloneObjectName(loaderName));
1325 }
1326
1327 /**
1328 * <p>Return the ClassLoaderRepository for that MBeanServer.
1329 * @return The ClassLoaderRepository for that MBeanServer.
1330 **/
1331 public ClassLoaderRepository getClassLoaderRepository() {
1332 /* Permission check */
1333 checkMBeanPermission(null, null, null, "getClassLoaderRepository");
1334 return secureClr;
1335 }
1336
1337 public MBeanServerDelegate getMBeanServerDelegate() {
1338 if (!interceptorsEnabled) throw new UnsupportedOperationException(
1339 "MBeanServerInterceptors are disabled.");
1340 return mBeanServerDelegateObject;
1341 }
1342
1343 // These methods are called by the JMX MBeanServerBuilder.
1344
1345 /**
1346 * This method creates a new MBeanServerDelegate for a new MBeanServer.
1347 * When creating a new MBeanServer the
1348 * {@link javax.management.MBeanServerBuilder} first calls this method
1349 * in order to create a new MBeanServerDelegate.
1350 * <br>Then it calls
1351 * <code>newMBeanServer(defaultDomain,outer,delegate,interceptors)</code>
1352 * passing the <var>delegate</var> that should be used by the MBeanServer
1353 * implementation.
1354 * <p>Note that the passed <var>delegate</var> might not be directly the
1355 * MBeanServerDelegate that was returned by this method. It could
1356 * be, for instance, a new object wrapping the previously
1357 * returned object.
1358 *
1359 * @return A new {@link javax.management.MBeanServerDelegate}.
1360 **/
1361 public static MBeanServerDelegate newMBeanServerDelegate() {
1362 return new MBeanServerDelegateImpl();
1363 }
1364
1365 /**
1366 * This method creates a new MBeanServer implementation object.
1367 * When creating a new MBeanServer the
1368 * {@link javax.management.MBeanServerBuilder} first calls
1369 * <code>newMBeanServerDelegate()</code> in order to obtain a new
1370 * {@link javax.management.MBeanServerDelegate} for the new
1371 * MBeanServer. Then it calls
1372 * <code>newMBeanServer(defaultDomain,outer,delegate)</code>
1373 * passing the <var>delegate</var> that should be used by the
1374 * MBeanServer implementation.
1375 * <p>Note that the passed <var>delegate</var> might not be directly the
1376 * MBeanServerDelegate that was returned by this implementation. It could
1377 * be, for instance, a new object wrapping the previously
1378 * returned delegate.
1379 * <p>The <var>outer</var> parameter is a pointer to the MBeanServer that
1380 * should be passed to the {@link javax.management.MBeanRegistration}
1381 * interface when registering MBeans inside the MBeanServer.
1382 * If <var>outer</var> is <code>null</code>, then the MBeanServer
1383 * implementation is free to use its own <code>this</code> pointer when
1384 * invoking the {@link javax.management.MBeanRegistration} interface.
1385 * <p>This makes it possible for a MBeanServer implementation to wrap
1386 * another MBeanServer implementation, in order to implement, e.g,
1387 * security checks, or to prevent access to the actual MBeanServer
1388 * implementation by returning a pointer to a wrapping object.
1389 *
1390 * @param defaultDomain Default domain of the new MBeanServer.
1391 * @param outer A pointer to the MBeanServer object that must be
1392 * passed to the MBeans when invoking their
1393 * {@link javax.management.MBeanRegistration} interface.
1394 * @param delegate A pointer to the MBeanServerDelegate associated
1395 * with the new MBeanServer. The new MBeanServer must register
1396 * this MBean in its MBean repository.
1397 * @param interceptors If <code>true</code>,
1398 * {@link MBeanServerInterceptor}s will be enabled (default is
1399 * <code>false</code>).
1400 * Note: this parameter is not taken into account by this
1401 * implementation - the default value <code>false</code> is
1402 * always used.
1403 * @return A new private implementation of an MBeanServer.
1404 * @see #interceptorsEnabled
1405 * @see javax.management.MBeanServerBuilder
1406 * @see com.sun.jmx.mbeanserver.JmxMBeanServerBuilder
1407 **/
1408 public static MBeanServer newMBeanServer(String defaultDomain,
1409 MBeanServer outer,
1410 MBeanServerDelegate delegate,
1411 boolean interceptors) {
1412 // Determine whether to use fair locking for the repository.
1413 // Default is true.
1414 final boolean fairLock = DEFAULT_FAIR_LOCK_POLICY;
1415
1416 // This constructor happens to disregard the value of the interceptors
1417 // flag - that is, it always uses the default value - false.
1418 // This is admitedly a bug, but we chose not to fix it for now
1419 // since we would rather not have anybody depending on the Sun private
1420 // interceptor APIs - which is most probably going to be removed and
1421 // replaced by a public (javax) feature in the future.
1422 //
1423 return new JmxMBeanServer(defaultDomain,outer,delegate,null,
1424 interceptors,fairLock);
1425 }
1426
1427 // JMX OBJECT CLONING
1428 //-------------------
1429
1430 /**
1431 * Clone object name.
1432 */
1433 private ObjectName cloneObjectName(ObjectName name) {
1434 if (name != null) {
1435 return ObjectName.getInstance(name);
1436 }
1437 return name;
1438 }
1439
1440 /**
1441 * Clone attribute.
1442 */
1443 private Attribute cloneAttribute(Attribute attribute) {
1444 if (attribute != null) {
1445 if (!attribute.getClass().equals(Attribute.class)) {
1446 return new Attribute(attribute.getName(), attribute.getValue());
1447 }
1448 }
1449 return attribute;
1450 }
1451
1452 /**
1453 * Clone attribute list.
1454 */
1455 private AttributeList cloneAttributeList(AttributeList list) {
1456 if (list != null) {
1457 if (!list.getClass().equals(AttributeList.class)) {
1458 // Create new attribute list
1459 //
1460 AttributeList newList = new AttributeList(list.size());
1461
1462 // Iterate through list and replace non JMX attributes
1463 //
1464 for (Iterator i = list.iterator(); i.hasNext(); ) {
1465 Attribute attribute = (Attribute) i.next();
1466 newList.add(cloneAttribute(attribute));
1467 }
1468 return newList;
1469 } else {
1470 // Iterate through list and replace non JMX attributes
1471 //
1472 for (int i = 0; i < list.size(); i++) {
1473 Attribute attribute = (Attribute) list.get(i);
1474 if (!attribute.getClass().equals(Attribute.class)) {
1475 list.set(i, cloneAttribute(attribute));
1476 }
1477 }
1478 return list;
1479 }
1480 }
1481 return list;
1482 }
1483
1484 // SECURITY CHECKS
1485 //----------------
1486
1487 private static void checkMBeanPermission(String classname,
1488 String member,
1489 ObjectName objectName,
1490 String actions)
1491 throws SecurityException {
1492 SecurityManager sm = System.getSecurityManager();
1493 if (sm != null) {
1494 Permission perm = new MBeanPermission(classname,
1495 member,
1496 objectName,
1497 actions);
1498 sm.checkPermission(perm);
1499 }
1500 }
1501
1502}