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