KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > mx > server > MBeanServerImpl


1 /*
2   * JBoss, Home of Professional Open Source
3   * Copyright 2005, JBoss Inc., and individual contributors as indicated
4   * by the @authors tag. See the copyright.txt in the distribution for a
5   * full listing of individual contributors.
6   *
7   * This is free software; you can redistribute it and/or modify it
8   * under the terms of the GNU Lesser General Public License as
9   * published by the Free Software Foundation; either version 2.1 of
10   * the License, or (at your option) any later version.
11   *
12   * This software is distributed in the hope that it will be useful,
13   * but WITHOUT ANY WARRANTY; without even the implied warranty of
14   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15   * Lesser General Public License for more details.
16   *
17   * You should have received a copy of the GNU Lesser General Public
18   * License along with this software; if not, write to the Free
19   * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20   * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
21   */

22 package org.jboss.mx.server;
23
24 import java.io.ByteArrayInputStream JavaDoc;
25 import java.io.IOException JavaDoc;
26 import java.io.ObjectInputStream JavaDoc;
27 import java.lang.reflect.Constructor JavaDoc;
28 import java.lang.reflect.InvocationTargetException JavaDoc;
29 import java.util.ArrayList JavaDoc;
30 import java.util.HashMap JavaDoc;
31 import java.util.HashSet JavaDoc;
32 import java.util.Iterator JavaDoc;
33 import java.util.List JavaDoc;
34 import java.util.Map JavaDoc;
35 import java.util.Set JavaDoc;
36 import java.security.ProtectionDomain JavaDoc;
37 import java.security.AccessController JavaDoc;
38 import java.security.PrivilegedAction JavaDoc;
39 import java.security.PrivilegedExceptionAction JavaDoc;
40 import java.security.PrivilegedActionException JavaDoc;
41
42 import javax.management.Attribute JavaDoc;
43 import javax.management.AttributeList JavaDoc;
44 import javax.management.AttributeNotFoundException JavaDoc;
45 import javax.management.InstanceAlreadyExistsException JavaDoc;
46 import javax.management.InstanceNotFoundException JavaDoc;
47 import javax.management.IntrospectionException JavaDoc;
48 import javax.management.InvalidAttributeValueException JavaDoc;
49 import javax.management.JMException JavaDoc;
50 import javax.management.ListenerNotFoundException JavaDoc;
51 import javax.management.MBeanException JavaDoc;
52 import javax.management.MBeanInfo JavaDoc;
53 import javax.management.MBeanParameterInfo JavaDoc;
54 import javax.management.MBeanRegistrationException JavaDoc;
55 import javax.management.MBeanServer JavaDoc;
56 import javax.management.MBeanServerDelegate JavaDoc;
57 import javax.management.NotCompliantMBeanException JavaDoc;
58 import javax.management.NotificationBroadcaster JavaDoc;
59 import javax.management.NotificationFilter JavaDoc;
60 import javax.management.NotificationListener JavaDoc;
61 import javax.management.ObjectInstance JavaDoc;
62 import javax.management.ObjectName JavaDoc;
63 import javax.management.OperationsException JavaDoc;
64 import javax.management.QueryExp JavaDoc;
65 import javax.management.ReflectionException JavaDoc;
66 import javax.management.RuntimeErrorException JavaDoc;
67 import javax.management.RuntimeMBeanException JavaDoc;
68 import javax.management.RuntimeOperationsException JavaDoc;
69 import javax.management.JMRuntimeException JavaDoc;
70 import javax.management.MBeanPermission JavaDoc;
71 import javax.management.MalformedObjectNameException JavaDoc;
72 import javax.management.MBeanTrustPermission JavaDoc;
73 import javax.management.loading.ClassLoaderRepository JavaDoc;
74 import javax.management.modelmbean.DescriptorSupport JavaDoc;
75 import javax.management.modelmbean.ModelMBean JavaDoc;
76 import javax.management.modelmbean.ModelMBeanAttributeInfo JavaDoc;
77 import javax.management.modelmbean.ModelMBeanConstructorInfo JavaDoc;
78 import javax.management.modelmbean.ModelMBeanInfo JavaDoc;
79 import javax.management.modelmbean.ModelMBeanInfoSupport JavaDoc;
80 import javax.management.modelmbean.ModelMBeanNotificationInfo JavaDoc;
81 import javax.management.modelmbean.ModelMBeanOperationInfo JavaDoc;
82
83 import org.jboss.logging.Logger;
84 import org.jboss.mx.loading.LoaderRepository;
85 import org.jboss.mx.modelmbean.ModelMBeanConstants;
86 import org.jboss.mx.modelmbean.RequiredModelMBeanInstantiator;
87 import org.jboss.mx.notification.MBeanServerListenerRegistry;
88 import org.jboss.mx.server.registry.MBeanEntry;
89 import org.jboss.mx.server.registry.MBeanRegistry;
90 import org.jboss.mx.service.ServiceConstants;
91 import org.jboss.mx.util.JMXExceptionDecoder;
92 import org.jboss.mx.util.PropertyAccess;
93 import org.jboss.util.NestedRuntimeException;
94
95 /**
96  * MBean server implementation.
97  *
98  * The MBean server behaviour can be configured by setting the following
99  * system properties: <ul>
100  * <li><tt>jbossmx.loader.repository.class</tt>
101  ({@link ServerConstants#LOADER_REPOSITORY_CLASS_PROPERTY LOADER_REPOSITORY_CLASS_PROPERTY})</li>
102  * <li><tt>jbossmx.mbean.registry.class</tt>
103  ({@link ServerConstants#MBEAN_REGISTRY_CLASS_PROPERTY MBEAN_REGISTRY_CLASS_PROPERTY})</li>
104  * <li><tt>jbossmx.required.modelmbean.class</tt>
105  ({@link ServerConstants#REQUIRED_MODELMBEAN_CLASS_PROPERTY REQUIRED_MODELMBEAN_CLASS_PROPERTY})</li>
106  * </ul>
107  *
108  * The loader repository is used for managing class loaders in the MBean server.
109  * The default repository uses the <tt>UnifiedLoaderRepository</tt> implementation
110  * ({@link ServerConstants#DEFAULT_LOADER_REPOSITORY_CLASS DEFAULT_LOADER_REPOSITORY_CLASS}).<p>
111  *
112  * The default registry is
113  * ({@link ServerConstants#DEFAULT_MBEAN_REGISTRY_CLASS DEFAULT_MBEAN_REGISTRY_CLASS}).<p>
114  *
115  * The <tt>RequiredModelMBean</tt> uses <tt>XMBean</tt> implementation by default
116  * ({@link ServerConstants#DEFAULT_REQUIRED_MODELMBEAN_CLASS DEFAULT_REQUIRED_MODELMBEAN_CLASS}).
117  *
118  * @see javax.management.MBeanServer
119  * @see javax.management.modelmbean.RequiredModelMBean
120  * @see org.jboss.mx.server.ServerConstants
121  * @see org.jboss.mx.loading.LoaderRepository
122  * @see org.jboss.mx.loading.UnifiedLoaderRepository3
123  * @see org.jboss.mx.modelmbean.XMBean
124  *
125  * @author <a HREF="mailto:juha@jboss.org">Juha Lindfors</a>.
126  * @author <a HREF="mailto:trevor@protocool.com">Trevor Squires</a>.
127  * @author <a HREF="mailto:Adrian.Brock@HappeningTimes.com">Adrian Brock</a>.
128  * @author <a HREF="mailto:thomas.diesler@jboss.com">Thomas Diesler</a>.
129  * @author Scott.Stark@jboss.org
130  * @version $Revision: 57108 $
131  */

132 public class MBeanServerImpl
133    implements MBeanServer JavaDoc, ServerConstants, ServiceConstants, ModelMBeanConstants
134 {
135    // Constants ------------------------------------------------------
136

137    /**
138     * No parameters array
139     */

140    private static final Object JavaDoc[] NOPARAMS = new Object JavaDoc[0];
141
142    /**
143     * No signature array
144     */

145    private static final String JavaDoc[] NOSIG = new String JavaDoc[0];
146
147    // Attributes ----------------------------------------------------
148

149    /**
150     * The wrapping MBeanServer
151     */

152    protected MBeanServer JavaDoc outer = null;
153
154    /**
155     * Registry used by this server to map MBean object names to resource references.
156     */

157    protected MBeanRegistry registry = null;
158
159    /**
160     * The notification registrations
161     */

162    private MBeanServerListenerRegistry listeners = new MBeanServerListenerRegistry();
163
164    /**
165     * This server's class loader repository
166     */

167    private ClassLoaderRepository JavaDoc classLoaderRepository;
168
169    // Static --------------------------------------------------------
170

171    /**
172     * The logger
173     */

174    private static Logger log = Logger.getLogger(MBeanServerImpl.class);
175
176    
177    // Constructors --------------------------------------------------
178

179    /**
180     * Creates an MBean server implementation with a given default domain name and
181     * registers the mandatory server delegate MBean to the server
182     * ({@link ServerConstants#MBEAN_SERVER_DELEGATE MBEAN_SERVER_DELEGATE}).
183     *
184     * @param defaultDomain default domain name
185     * @param outer the wrapping MBeanServer, passed to MBeans
186     * at registration.
187     * @param delegate the delegate to use
188     * for Notifications.
189     */

190    public MBeanServerImpl(String JavaDoc defaultDomain, MBeanServer JavaDoc outer, MBeanServerDelegate JavaDoc delegate)
191    {
192       // Determine the MBeanServer to pass to MBeans
193
if (outer == null)
194          this.outer = this;
195       else
196          this.outer = outer;
197
198       // the very first thing to do is to create a class loader repository
199
this.classLoaderRepository = getClassLoaderRepository();
200
201       // the second first thing to do is to create a registry instance
202
this.registry = createRegistry(defaultDomain);
203       
204       // The first MBean to be registered should be the server delegate
205
// to guarantee correct functionality (other MBeans may be dependent
206
// on the existence of the delegate).
207
try
208       {
209          // the magic token that allows us to register to the
210
// protected JMImplementation domain
211
HashMap JavaDoc valueMap = new HashMap JavaDoc();
212          valueMap.put(JMI_DOMAIN, JMI_DOMAIN);
213
214          // register the delegate
215
registry.registerMBean(delegate,
216                  new ObjectName JavaDoc(MBEAN_SERVER_DELEGATE),
217                  valueMap);
218          
219          // We expose the registry as an MBean for other components
220
ModelMBean JavaDoc rmm = RequiredModelMBeanInstantiator.instantiate();
221          rmm.setModelMBeanInfo(getRegistryManagementInterface());
222          rmm.setManagedResource(registry, "ObjectReference");
223
224          // register the registry MBean
225
registry.registerMBean(rmm, new ObjectName JavaDoc(MBEAN_REGISTRY), valueMap);
226          
227          // register the loader repository
228
//String loaderClassMBeanName = classLoaderRepository.getClass().getName() + "MBean";
229
//ClassLoader cl = classLoaderRepository.getClass().getClassLoader();
230
//Class mbean = cl.loadClass(loaderClassMBeanName);
231

232          //there must be a class with the MBean extension.
233
ObjectName JavaDoc loaderName = new ObjectName JavaDoc(DEFAULT_LOADER_NAME);
234          registry.registerMBean(classLoaderRepository, loaderName, valueMap);
235
236       }
237       catch (Exception JavaDoc e)
238       {
239          throw new RuntimeException JavaDoc("Cannot create MBeanServer", e);
240       }
241    }
242
243    // MBeanServer implementation ------------------------------------
244

245    public Object JavaDoc instantiate(String JavaDoc className)
246            throws ReflectionException JavaDoc, MBeanException JavaDoc
247    {
248       return instantiate(className, (ClassLoader JavaDoc) null, NOPARAMS, NOSIG);
249    }
250
251    public Object JavaDoc instantiate(String JavaDoc className, Object JavaDoc[] params, String JavaDoc[] signature)
252            throws ReflectionException JavaDoc, MBeanException JavaDoc
253    {
254       return instantiate(className, (ClassLoader JavaDoc) null, params, signature);
255    }
256
257    public Object JavaDoc instantiate(String JavaDoc className, ObjectName JavaDoc loaderName)
258            throws ReflectionException JavaDoc, MBeanException JavaDoc, InstanceNotFoundException JavaDoc
259    {
260       return instantiate(className, loaderName, NOPARAMS, NOSIG);
261    }
262
263    public Object JavaDoc instantiate(String JavaDoc className, ObjectName JavaDoc loaderName, Object JavaDoc[] params, String JavaDoc[] signature)
264            throws ReflectionException JavaDoc, MBeanException JavaDoc, InstanceNotFoundException JavaDoc
265    {
266       ClassLoader JavaDoc cl = null;
267
268       // if instantiate() is called with null loader name, we use the cl that
269
// loaded the MBean server (see javadoc)
270

271       try
272       {
273          if (loaderName != null)
274             cl = (ClassLoader JavaDoc) registry.get(loaderName).getResourceInstance();
275       }
276       catch (ClassCastException JavaDoc e)
277       {
278          throw new ReflectionException JavaDoc(e, loaderName + " is not a class loader.");
279       }
280
281       if (cl == null)
282          cl = this.getClass().getClassLoader();
283       if (cl == null)
284          cl = ClassLoader.getSystemClassLoader();
285
286       return instantiate(className, cl, params, signature);
287    }
288
289    public ObjectInstance JavaDoc createMBean(String JavaDoc className, ObjectName JavaDoc name)
290            throws ReflectionException JavaDoc, InstanceAlreadyExistsException JavaDoc, MBeanRegistrationException JavaDoc, MBeanException JavaDoc, NotCompliantMBeanException JavaDoc
291    {
292       try
293       {
294          Object JavaDoc mbean = instantiate(className);
295          return registerMBean(mbean, name, (ClassLoader JavaDoc) null);
296       }
297       catch (SecurityException JavaDoc e)
298       {
299          throw e;
300       }
301       catch (ReflectionException JavaDoc refex)
302       {
303          // Note, the CTS wants a NotCompliantMBeanException for this case
304
if (refex.getCause() instanceof InstantiationException JavaDoc)
305             throw new NotCompliantMBeanException JavaDoc("Cannot instanciate MBean: " + className);
306          else
307             throw refex;
308       }
309    }
310
311    public ObjectInstance JavaDoc createMBean(String JavaDoc className, ObjectName JavaDoc name, Object JavaDoc[] params, String JavaDoc[] signature)
312            throws ReflectionException JavaDoc, InstanceAlreadyExistsException JavaDoc, MBeanRegistrationException JavaDoc, MBeanException JavaDoc, NotCompliantMBeanException JavaDoc
313    {
314       try
315       {
316          Object JavaDoc mbean = instantiate(className, params, signature);
317          return registerMBean(mbean, name, (ClassLoader JavaDoc) null);
318       }
319       catch (ReflectionException JavaDoc refex)
320       {
321          return handleExceptionOnCreate(refex, className);
322       }
323    }
324
325    public ObjectInstance JavaDoc createMBean(String JavaDoc className, ObjectName JavaDoc name, ObjectName JavaDoc loaderName)
326            throws ReflectionException JavaDoc, InstanceAlreadyExistsException JavaDoc, MBeanRegistrationException JavaDoc, MBeanException JavaDoc, NotCompliantMBeanException JavaDoc, InstanceNotFoundException JavaDoc
327    {
328       try
329       {
330          Object JavaDoc mbean = instantiate(className, loaderName);
331          return registerMBean(mbean, name, loaderName);
332       }
333       catch (ReflectionException JavaDoc refex)
334       {
335          return handleExceptionOnCreate(refex, className);
336       }
337    }
338
339    public ObjectInstance JavaDoc createMBean(String JavaDoc className, ObjectName JavaDoc name, ObjectName JavaDoc loaderName, Object JavaDoc[] params, String JavaDoc[] signature)
340            throws ReflectionException JavaDoc, InstanceAlreadyExistsException JavaDoc, MBeanRegistrationException JavaDoc, MBeanException JavaDoc, NotCompliantMBeanException JavaDoc, InstanceNotFoundException JavaDoc
341    {
342       try
343       {
344          Object JavaDoc mbean = instantiate(className, loaderName, params, signature);
345          return registerMBean(mbean, name, loaderName);
346       }
347       catch (ReflectionException JavaDoc refex)
348       {
349          return handleExceptionOnCreate(refex, className);
350       }
351    }
352
353    /**
354     * The CTS wants a NotCompliantMBeanException in case the MBean cannot be created.
355     * We need this, because instanciate cannot throw NotCompliantMBeanException.
356     */

357    private ObjectInstance JavaDoc handleExceptionOnCreate(ReflectionException JavaDoc refex, String JavaDoc className)
358            throws NotCompliantMBeanException JavaDoc, ReflectionException JavaDoc
359    {
360       if (refex.getCause() instanceof InstantiationException JavaDoc)
361          throw new NotCompliantMBeanException JavaDoc("Cannot instanciate MBean: " + className);
362
363       throw refex;
364    }
365
366    /**
367     * Registers a pre-existing object as an MBean with the MBean server. If the object name given is null,
368     * the MBean must provide its own name by implementing the MBeanRegistration interface and returning the name
369     * from the preRegister method.
370     */

371    public ObjectInstance JavaDoc registerMBean(Object JavaDoc object, ObjectName JavaDoc name)
372            throws InstanceAlreadyExistsException JavaDoc,
373            MBeanRegistrationException JavaDoc,
374            NotCompliantMBeanException JavaDoc
375    {
376       return registerMBean(object, name, (ClassLoader JavaDoc) null);
377    }
378
379    public void unregisterMBean(ObjectName JavaDoc name)
380            throws InstanceNotFoundException JavaDoc, MBeanRegistrationException JavaDoc
381    {
382       // Get the mbean to remove
383
MBeanEntry entry = registry.get(name);
384       Object JavaDoc mbean = entry.getResourceInstance();
385       name = entry.getObjectName();
386
387       checkMBeanPermission(entry.getResourceClassName(), null, name, "unregisterMBean");
388
389       try
390       {
391          final Object JavaDoc[] args = {name};
392          final String JavaDoc[] sig = {ObjectName JavaDoc.class.getName()};
393          try
394          {
395             AccessController.doPrivileged(
396                new PrivilegedExceptionAction JavaDoc()
397                {
398                   public Object JavaDoc run() throws Exception JavaDoc
399                   {
400                      return invoke(new ObjectName JavaDoc(MBEAN_REGISTRY),
401                         "unregisterMBean", args, sig);
402                   }
403                }
404             );
405          }
406          catch(PrivilegedActionException JavaDoc e)
407          {
408             throw e.getException();
409          }
410       }
411       catch (Throwable JavaDoc t)
412       {
413          Throwable JavaDoc result = JMXExceptionDecoder.decodeToJMXException(t);
414          if (result instanceof InstanceNotFoundException JavaDoc)
415             throw (InstanceNotFoundException JavaDoc) result;
416          if (result instanceof MBeanRegistrationException JavaDoc)
417             throw (MBeanRegistrationException JavaDoc) result;
418          if ( result instanceof JMRuntimeException JavaDoc )
419             throw (JMRuntimeException JavaDoc) result;
420          if (result instanceof MBeanException JavaDoc)
421          {
422             MBeanException JavaDoc e = (MBeanException JavaDoc) result;
423             t = e.getTargetException();
424             if (t instanceof InstanceNotFoundException JavaDoc)
425                throw (InstanceNotFoundException JavaDoc) t;
426             if (t instanceof MBeanRegistrationException JavaDoc)
427                throw (MBeanRegistrationException JavaDoc) t;
428          }
429          if (result instanceof RuntimeException JavaDoc)
430             throw new RuntimeMBeanException JavaDoc((RuntimeException JavaDoc) result);
431          if (result instanceof Error JavaDoc)
432             throw new RuntimeErrorException JavaDoc((Error JavaDoc) result);
433
434          // for some other reason, unregistration failed
435
throw new MBeanRegistrationException JavaDoc(new InvocationTargetException JavaDoc(t), "Cannot unregister MBean");
436       }
437       
438       // Unregistration worked, remove any proxies for a broadcaster
439
if (mbean instanceof NotificationBroadcaster JavaDoc)
440          listeners.remove(name);
441    }
442
443    public ObjectInstance JavaDoc getObjectInstance(ObjectName JavaDoc name)
444            throws InstanceNotFoundException JavaDoc
445    {
446       ObjectInstance JavaDoc oi = registry.getObjectInstance(name);
447       checkMBeanPermission(oi.getClassName(), null, name,
448          "getObjectInstance");
449
450       return oi;
451    }
452
453    public Set JavaDoc queryMBeans(ObjectName JavaDoc name, QueryExp JavaDoc query)
454    {
455       // At least one mbean must be queriable
456
checkMBeanPermission(null, null, null, "queryMBeans");
457
458       // Set up the query
459
Set JavaDoc result = new HashSet JavaDoc();
460       if (query != null)
461          query.setMBeanServer(outer);
462
463       SecurityManager JavaDoc sm = System.getSecurityManager();
464       // Get the possible MBeans
465
List JavaDoc entries = registry.findEntries(name);
466       Iterator JavaDoc iterator = entries.iterator();
467       while (iterator.hasNext())
468       {
469          // Check each MBean against the query
470
MBeanEntry entry = (MBeanEntry) iterator.next();
471          ObjectName JavaDoc objectName = entry.getObjectName();
472          // The permission check must be done before the query is applied
473
if( sm != null )
474          {
475             try
476             {
477                checkMBeanPermission(entry.getResourceClassName(), null,
478                   objectName, "queryMBeans");
479             }
480             catch(SecurityException JavaDoc e)
481             {
482                if( log.isTraceEnabled() )
483                   log.trace("Excluded mbean due to security: "+objectName);
484                continue;
485             }
486          }
487          // Check the mbean against the query
488
if (queryMBean(objectName, query) == true)
489          {
490             try
491             {
492                ObjectInstance JavaDoc instance = registry.getObjectInstance(objectName);
493                result.add(instance);
494             }
495             catch (InstanceNotFoundException JavaDoc ignored)
496             {
497             }
498          }
499       }
500
501       return result;
502    }
503
504    public Set JavaDoc queryNames(ObjectName JavaDoc name, QueryExp JavaDoc query)
505    {
506       // At least one mbean must be queriable
507
checkMBeanPermission(null, null, null, "queryNames");
508
509       // Set up the query
510
Set JavaDoc result = new HashSet JavaDoc();
511       if (query != null)
512          query.setMBeanServer(outer);
513
514       SecurityManager JavaDoc sm = System.getSecurityManager();
515       // Get the possible MBeans
516
List JavaDoc entries = registry.findEntries(name);
517       Iterator JavaDoc iterator = entries.iterator();
518       while (iterator.hasNext())
519       {
520          // Check each MBean against the query
521
MBeanEntry entry = (MBeanEntry) iterator.next();
522          ObjectName JavaDoc objectName = entry.getObjectName();
523          // The permission check must be done before the query is applied
524
if( sm != null )
525          {
526             try
527             {
528                checkMBeanPermission(entry.getResourceClassName(), null,
529                   objectName, "queryNames");
530             }
531             catch(SecurityException JavaDoc e)
532             {
533                if( log.isTraceEnabled() )
534                   log.trace("Excluded mbean due to security: "+objectName);
535                continue;
536             }
537          }
538          // Check the mbean against the query
539
if (queryMBean(objectName, query) == true)
540             result.add(objectName);
541       }
542
543       return result;
544    }
545
546    public boolean isRegistered(ObjectName JavaDoc name)
547    {
548       return registry.contains(name);
549    }
550
551    public java.lang.Integer JavaDoc getMBeanCount()
552    {
553       return new Integer JavaDoc(registry.getSize());
554    }
555
556    public Object JavaDoc getAttribute(ObjectName JavaDoc name, String JavaDoc attribute)
557            throws MBeanException JavaDoc, AttributeNotFoundException JavaDoc, InstanceNotFoundException JavaDoc, ReflectionException JavaDoc
558    {
559       MBeanEntry entry = registry.get(name);
560       checkMBeanPermission(entry.getResourceClassName(), attribute, name,
561          "getAttribute");
562
563       MBeanInvoker mbean = entry.getInvoker();
564
565       return mbean.getAttribute(attribute);
566    }
567
568    public AttributeList JavaDoc getAttributes(ObjectName JavaDoc name, String JavaDoc[] attributes)
569            throws InstanceNotFoundException JavaDoc, ReflectionException JavaDoc
570    {
571       MBeanEntry entry = registry.get(name);
572       String JavaDoc className = entry.getResourceClassName();
573       /* Access to an attribute is required and this check will fail only
574       if access to no attributes are allowed and will result in a security
575       exception rather than an empty list.
576       */

577       checkMBeanPermission(className, null, name, "getAttribute");
578       
579       MBeanInvoker mbean = entry.getInvoker();
580       AttributeList JavaDoc list = mbean.getAttributes(attributes);
581       SecurityManager JavaDoc sm = System.getSecurityManager();
582       if( sm != null )
583       {
584          // Remove any attributes that are not allowed
585
Iterator JavaDoc iter = list.iterator();
586          while( iter.hasNext() )
587          {
588             Attribute JavaDoc attr = (Attribute JavaDoc) iter.next();
589             String JavaDoc aname = attr.getName();
590             try
591             {
592                checkMBeanPermission(className, aname, name, "getAttribute");
593             }
594             catch(SecurityException JavaDoc e)
595             {
596                if( log.isTraceEnabled() )
597                   log.trace("Excluded attribute due to security: "+aname);
598                iter.remove();
599             }
600          }
601       }
602       return list;
603    }
604
605    public void setAttribute(ObjectName JavaDoc name, Attribute JavaDoc attribute)
606            throws InstanceNotFoundException JavaDoc, AttributeNotFoundException JavaDoc, InvalidAttributeValueException JavaDoc, MBeanException JavaDoc, ReflectionException JavaDoc
607    {
608       MBeanEntry entry = registry.get(name);
609       String JavaDoc attributeName = null;
610       if (attribute != null)
611          attributeName = attribute.getName();
612       checkMBeanPermission(entry.getResourceClassName(), attributeName,
613          name, "setAttribute");
614
615       MBeanInvoker mbean = entry.getInvoker();
616
617       mbean.setAttribute(attribute);
618    }
619
620    public AttributeList JavaDoc setAttributes(ObjectName JavaDoc name, AttributeList JavaDoc attributes)
621            throws InstanceNotFoundException JavaDoc, ReflectionException JavaDoc
622    {
623       MBeanEntry entry = registry.get(name);
624
625       String JavaDoc className = entry.getResourceClassName();
626       /* Access to an attribute is required and this check will fail only
627       if access to no attributes are allowed and will result in a security
628       exception rather than an empty list.
629       */

630       checkMBeanPermission(className, null, name, "setAttribute");
631
632       MBeanInvoker mbean = entry.getInvoker();
633       AttributeList JavaDoc list = mbean.setAttributes(attributes);
634       SecurityManager JavaDoc sm = System.getSecurityManager();
635       if( sm != null )
636       {
637          // Remove any attributes that are not allowed
638
Iterator JavaDoc iter = list.iterator();
639          while( iter.hasNext() )
640          {
641             Attribute JavaDoc attr = (Attribute JavaDoc) iter.next();
642             String JavaDoc aname = attr.getName();
643             try
644             {
645                checkMBeanPermission(className, aname, name, "setAttribute");
646             }
647             catch(SecurityException JavaDoc e)
648             {
649                if( log.isTraceEnabled() )
650                   log.trace("Excluded attribute due to security: "+aname);
651                iter.remove();
652             }
653          }
654       }
655       return list;
656    }
657
658    public Object JavaDoc invoke(ObjectName JavaDoc name, String JavaDoc operationName, Object JavaDoc[] params,
659       String JavaDoc[] signature)
660       throws InstanceNotFoundException JavaDoc, MBeanException JavaDoc, ReflectionException JavaDoc
661    {
662       MBeanEntry entry = registry.get(name);
663       checkMBeanPermission(entry.getResourceClassName(), operationName, name,
664          "invoke");
665
666       MBeanInvoker mbean = entry.getInvoker();
667
668       return mbean.invoke(operationName, params, signature);
669    }
670
671    public MBeanInfo JavaDoc getMBeanInfo(ObjectName JavaDoc name)
672       throws InstanceNotFoundException JavaDoc, IntrospectionException JavaDoc,
673       ReflectionException JavaDoc
674    {
675       MBeanEntry entry = registry.get(name);
676       checkMBeanPermission(entry.getResourceClassName(), null, name,
677          "getMBeanInfo");
678       try
679       {
680          MBeanInvoker invoker = entry.getInvoker();
681          return invoker.getMBeanInfo();
682       }
683       catch (Exception JavaDoc e)
684       {
685          JMException JavaDoc result = ExceptionHandler.handleException(e);
686          if (result instanceof InstanceNotFoundException JavaDoc)
687             throw (InstanceNotFoundException JavaDoc) result;
688          if (result instanceof IntrospectionException JavaDoc)
689             throw (IntrospectionException JavaDoc) result;
690          if (result instanceof ReflectionException JavaDoc)
691             throw (ReflectionException JavaDoc) result;
692          throw new RuntimeException JavaDoc("Cannot obtain MBeanInfo " + name, result);
693       }
694    }
695
696    public String JavaDoc getDefaultDomain()
697    {
698       return registry.getDefaultDomain();
699    }
700
701    public String JavaDoc[] getDomains()
702    {
703       checkMBeanPermission(null, null, null, "getDomains");
704       String JavaDoc[] domains = registry.getDomains();
705       SecurityManager JavaDoc sm = System.getSecurityManager();
706       if( sm != null )
707       {
708          ArrayList JavaDoc tmp = new ArrayList JavaDoc();
709          // Remove any domains that are not allowed
710
int length = domains != null ? domains.length : 0;
711          for(int n = 0; n < length; n ++)
712          {
713             String JavaDoc domain = domains[n];
714             try
715             {
716                ObjectName JavaDoc name = new ObjectName JavaDoc(domain, "x", "x");
717                checkMBeanPermission(null, null, name, "getDomains");
718                tmp.add(domain);
719             }
720             catch(MalformedObjectNameException JavaDoc e)
721             {
722                // Should not be possible
723
}
724             catch(SecurityException JavaDoc e)
725             {
726                if( log.isTraceEnabled() )
727                   log.trace("Excluded domain due to security: "+domain);
728             }
729          }
730          domains = new String JavaDoc[tmp.size()];
731          tmp.toArray(domains);
732       }
733       return domains;
734    }
735
736    /**
737     * Adds a listener to a registered MBean.
738     *
739     * A notification emitted by the MBean will be forwarded by the MBeanServer to the listener.
740     * If the source of the notification is a reference to the MBean object, the MBean server will replace
741     * it by the MBean's ObjectName. Otherwise the source is unchanged.
742     */

743    public void addNotificationListener(ObjectName JavaDoc name, NotificationListener JavaDoc listener, NotificationFilter JavaDoc filter, Object JavaDoc handback)
744            throws InstanceNotFoundException JavaDoc
745    {
746       MBeanEntry entry = registry.get(name);
747       if (NotificationBroadcaster JavaDoc.class.isInstance(entry.getResourceInstance()) == false)
748          throw new RuntimeOperationsException JavaDoc(new IllegalArgumentException JavaDoc("The MBean " + name + " exists but does not implement the NotificationBroadcaster interface."));
749
750       if (listener == null)
751          throw new RuntimeOperationsException JavaDoc(new IllegalArgumentException JavaDoc("Cannot add null listener"));
752
753       checkMBeanPermission(entry.getResourceClassName(), null, name,
754          "addNotificationListener");
755
756       ClassLoader JavaDoc newTCL = entry.getClassLoader();
757       NotificationBroadcaster JavaDoc broadcaster = entry.getInvoker();
758
759       ClassLoader JavaDoc oldTCL = TCLAction.UTIL.getContextClassLoader();
760       final boolean setCl = newTCL != oldTCL && newTCL != null;
761       try
762       {
763          if (setCl)
764             TCLAction.UTIL.setContextClassLoader(newTCL);
765
766          listeners.add(entry.getObjectName(), broadcaster, listener, filter, handback);
767       }
768       finally
769       {
770          if (setCl)
771             TCLAction.UTIL.setContextClassLoader(oldTCL);
772       }
773    }
774
775    /**
776     * Adds a listener to a registered MBean.
777     *
778     * A notification emitted by the MBean will be forwarded by the MBeanServer to the listener.
779     * If the source of the notification is a reference to the MBean object, the MBean server will replace
780     * it by the MBean's ObjectName. Otherwise the source is unchanged.
781     *
782     * The listener object that receives notifications is the one that is registered with the given name at the time this
783     * method is called. Even if it is subsequently unregistered, it will continue to receive notifications.
784     */

785    public void addNotificationListener(ObjectName JavaDoc name, ObjectName JavaDoc listener, NotificationFilter JavaDoc filter, Object JavaDoc handback)
786            throws InstanceNotFoundException JavaDoc
787    {
788       MBeanEntry entry = registry.get(name);
789       if (NotificationBroadcaster JavaDoc.class.isInstance(entry.getResourceInstance()) == false)
790          throw new RuntimeOperationsException JavaDoc(new IllegalArgumentException JavaDoc("The MBean " + name + " exists but does not implement the NotificationBroadcaster interface."));
791
792       MBeanEntry listenerEntry = registry.get(listener);
793       if (NotificationListener JavaDoc.class.isInstance(listenerEntry.getResourceInstance()) == false)
794          throw new RuntimeOperationsException JavaDoc(new IllegalArgumentException JavaDoc("The MBean " + listener + " exists but does not implement the NotificationListener interface."));
795
796       checkMBeanPermission(entry.getResourceClassName(), null, name,
797          "addNotificationListener");
798
799       ClassLoader JavaDoc newTCL = entry.getClassLoader();
800       NotificationBroadcaster JavaDoc broadcaster = entry.getInvoker();
801
802       ClassLoader JavaDoc oldTCL = TCLAction.UTIL.getContextClassLoader();
803       final boolean setCl = newTCL != oldTCL && newTCL != null;
804       try
805       {
806          if (setCl)
807             TCLAction.UTIL.setContextClassLoader(newTCL);
808
809          listeners.add(entry.getObjectName(), broadcaster,
810                  (NotificationListener JavaDoc) registry.get(listener).getResourceInstance(), filter, handback);
811       }
812       finally
813       {
814          if (setCl)
815             TCLAction.UTIL.setContextClassLoader(oldTCL);
816       }
817    }
818
819    /**
820     * Removes a listener from a registered MBean.
821     *
822     * If the listener is registered more than once, perhaps with different filters or callbacks,
823     * this method will remove all those registrations.
824     */

825    public void removeNotificationListener(ObjectName JavaDoc name, NotificationListener JavaDoc listener)
826            throws InstanceNotFoundException JavaDoc, ListenerNotFoundException JavaDoc
827    {
828       MBeanEntry entry = registry.get(name);
829       if (NotificationBroadcaster JavaDoc.class.isInstance(entry.getResourceInstance()) == false)
830          throw new RuntimeOperationsException JavaDoc(new IllegalArgumentException JavaDoc("The MBean " + name + " exists but does not implement the NotificationBroadcaster interface."));
831
832       checkMBeanPermission(entry.getResourceClassName(), null, name,
833          "removeNotificationListener");
834
835       ClassLoader JavaDoc newTCL = entry.getClassLoader();
836
837       ClassLoader JavaDoc oldTCL = TCLAction.UTIL.getContextClassLoader();
838       final boolean setCl = newTCL != oldTCL && newTCL != null;
839       try
840       {
841          if (setCl)
842             TCLAction.UTIL.setContextClassLoader(newTCL);
843
844          listeners.remove(entry.getObjectName(), listener);
845       }
846       finally
847       {
848          if (setCl)
849             TCLAction.UTIL.setContextClassLoader(oldTCL);
850       }
851    }
852
853    /**
854     * Removes a listener from a registered MBean.
855     *
856     * If the listener is registered more than once, perhaps with different filters or callbacks,
857     * this method will remove all those registrations.
858     */

859    public void removeNotificationListener(ObjectName JavaDoc name, ObjectName JavaDoc listener)
860            throws InstanceNotFoundException JavaDoc, ListenerNotFoundException JavaDoc
861    {
862       MBeanEntry entry = registry.get(name);
863       if (NotificationBroadcaster JavaDoc.class.isInstance(entry.getResourceInstance()) == false)
864          throw new RuntimeOperationsException JavaDoc(new IllegalArgumentException JavaDoc("The MBean " + name + " exists but does not implement the NotificationBroadcaster interface."));
865
866       MBeanEntry listenerEntry = registry.get(listener);
867       if (NotificationListener JavaDoc.class.isInstance(listenerEntry.getResourceInstance()) == false)
868          throw new RuntimeOperationsException JavaDoc(new IllegalArgumentException JavaDoc("The MBean " + listener + " exists but does not implement the NotificationListener interface."));
869
870       checkMBeanPermission(entry.getResourceClassName(), null, name,
871          "removeNotificationListener");
872
873       ClassLoader JavaDoc newTCL = entry.getClassLoader();
874
875       ClassLoader JavaDoc oldTCL = TCLAction.UTIL.getContextClassLoader();
876       final boolean setCl = newTCL != oldTCL && newTCL != null;
877       try
878       {
879          if (setCl)
880             TCLAction.UTIL.setContextClassLoader(newTCL);
881
882          listeners.remove(entry.getObjectName(), (NotificationListener JavaDoc) registry.get(listener).getResourceInstance());
883       }
884       finally
885       {
886          if (setCl)
887             TCLAction.UTIL.setContextClassLoader(oldTCL);
888       }
889    }
890
891    /**
892     * Removes a listener from a registered MBean.
893     *
894     * The MBean must have a listener that exactly matches the given listener, filter, and handback parameters.
895     * If there is more than one such listener, only one is removed.
896     *
897     * The filter and handback parameters may be null if and only if they are null in a listener to be removed.
898     */

899    public void removeNotificationListener(ObjectName JavaDoc name,
900       NotificationListener JavaDoc listener, NotificationFilter JavaDoc filter, Object JavaDoc handback)
901       throws InstanceNotFoundException JavaDoc, ListenerNotFoundException JavaDoc
902    {
903       MBeanEntry entry = registry.get(name);
904       if (NotificationBroadcaster JavaDoc.class.isInstance(entry.getResourceInstance()) == false)
905          throw new RuntimeOperationsException JavaDoc(new IllegalArgumentException JavaDoc("The MBean " + name + " exists but does not implement the NotificationBroadcaster interface."));
906
907       checkMBeanPermission(entry.getResourceClassName(), null, name,
908          "removeNotificationListener");
909
910       ClassLoader JavaDoc newTCL = entry.getClassLoader();
911
912       ClassLoader JavaDoc oldTCL = TCLAction.UTIL.getContextClassLoader();
913       final boolean setCl = newTCL != oldTCL && newTCL != null;
914       try
915       {
916          if (setCl)
917             TCLAction.UTIL.setContextClassLoader(newTCL);
918
919          listeners.remove(entry.getObjectName(), listener, filter, handback);
920       }
921       finally
922       {
923          if (setCl)
924             TCLAction.UTIL.setContextClassLoader(oldTCL);
925       }
926    }
927
928    /**
929     * Removes a listener from a registered MBean.
930     *
931     * The MBean must have a listener that exactly matches the given listener, filter, and handback parameters.
932     * If there is more than one such listener, only one is removed.
933     *
934     * The filter and handback parameters may be null if and only if they are null in a listener to be removed.
935     */

936    public void removeNotificationListener(ObjectName JavaDoc name, ObjectName JavaDoc listener,
937       NotificationFilter JavaDoc filter, Object JavaDoc handback)
938       throws InstanceNotFoundException JavaDoc, ListenerNotFoundException JavaDoc
939    {
940       MBeanEntry entry = registry.get(name);
941       if (NotificationBroadcaster JavaDoc.class.isInstance(entry.getResourceInstance()) == false)
942          throw new RuntimeOperationsException JavaDoc(new IllegalArgumentException JavaDoc("The MBean " + name + " exists but does not implement the NotificationBroadcaster interface."));
943
944       MBeanEntry listenerEntry = registry.get(listener);
945       if (NotificationListener JavaDoc.class.isInstance(listenerEntry.getResourceInstance()) == false)
946          throw new RuntimeOperationsException JavaDoc(new IllegalArgumentException JavaDoc("The MBean " + listener + " exists but does not implement the NotificationListener interface."));
947
948       checkMBeanPermission(entry.getResourceClassName(), null, name,
949          "removeNotificationListener");
950
951       ClassLoader JavaDoc newTCL = entry.getClassLoader();
952
953       ClassLoader JavaDoc oldTCL = TCLAction.UTIL.getContextClassLoader();
954       final boolean setCl = newTCL != oldTCL && newTCL != null;
955       try
956       {
957          if (setCl)
958             TCLAction.UTIL.setContextClassLoader(newTCL);
959
960          listeners.remove(entry.getObjectName(), (NotificationListener JavaDoc) registry.get(listener).getResourceInstance(),
961                  filter, handback);
962       }
963       finally
964       {
965          if (setCl)
966             TCLAction.UTIL.setContextClassLoader(oldTCL);
967       }
968    }
969
970    public boolean isInstanceOf(ObjectName JavaDoc name, String JavaDoc className)
971            throws InstanceNotFoundException JavaDoc
972    {
973       // Get the MBean's class name
974
MBeanEntry entry = registry.get(name);
975       String JavaDoc mbeanClassName = entry.getResourceClassName();
976       checkMBeanPermission(mbeanClassName, null, name, "isInstanceOf");
977
978       // The names are the same
979
if (className.equals(mbeanClassName))
980          return true;
981
982       // Try to load both classes
983
Class JavaDoc mbeanClass = null;
984       Class JavaDoc testClass = null;
985       ClassLoader JavaDoc cl = getClassLoaderFor(name);
986       try
987       {
988          mbeanClass = cl.loadClass(mbeanClassName);
989          testClass = cl.loadClass(className);
990       }
991       catch (ClassNotFoundException JavaDoc e)
992       {
993          return false;
994       }
995
996       // Check whether it is assignable
997
if (testClass.isAssignableFrom(mbeanClass))
998          return true;
999       else
1000         return false;
1001   }
1002
1003   /**
1004    * @deprecated
1005    */

1006   public ObjectInputStream JavaDoc deserialize(ObjectName JavaDoc name, byte[] data) throws InstanceNotFoundException JavaDoc, OperationsException JavaDoc
1007   {
1008      try
1009      {
1010         ClassLoader JavaDoc cl = this.getClassLoaderFor(name);
1011         return new ObjectInputStreamWithClassLoader(new ByteArrayInputStream JavaDoc(data), cl);
1012      }
1013      catch (IOException JavaDoc e)
1014      {
1015         throw new OperationsException JavaDoc("I/O exception deserializing: " + e.getMessage());
1016      }
1017   }
1018
1019   /**
1020    * @deprecated
1021    */

1022   public ObjectInputStream JavaDoc deserialize(String JavaDoc className, byte[] data)
1023      throws OperationsException JavaDoc, ReflectionException JavaDoc
1024   {
1025      try
1026      {
1027         Class JavaDoc c = this.getClassLoaderRepository().loadClass(className);
1028         ClassLoader JavaDoc cl = c.getClassLoader();
1029         return new ObjectInputStreamWithClassLoader(new ByteArrayInputStream JavaDoc(data), cl);
1030      }
1031      catch (IOException JavaDoc e)
1032      {
1033         throw new OperationsException JavaDoc("I/O exception deserializing: " + e.getMessage());
1034      }
1035      catch (ClassNotFoundException JavaDoc e)
1036      {
1037         throw new ReflectionException JavaDoc(e, "Class not found from default repository: " + className);
1038      }
1039   }
1040
1041   /**
1042    * @deprecated
1043    */

1044   public ObjectInputStream JavaDoc deserialize(String JavaDoc className, ObjectName JavaDoc loaderName,
1045      byte[] data)
1046      throws InstanceNotFoundException JavaDoc, OperationsException JavaDoc, ReflectionException JavaDoc
1047   {
1048      try
1049      {
1050         ClassLoader JavaDoc cl = this.getClassLoader(loaderName);
1051         return new ObjectInputStreamWithClassLoader(new ByteArrayInputStream JavaDoc(data), cl);
1052      }
1053      catch (IOException JavaDoc e)
1054      {
1055         throw new OperationsException JavaDoc("I/O exception deserializing: " + e.getMessage());
1056      }
1057   }
1058
1059   public ClassLoader JavaDoc getClassLoaderFor(ObjectName JavaDoc name)
1060           throws InstanceNotFoundException JavaDoc
1061   {
1062      MBeanEntry entry = registry.get(name);
1063      checkMBeanPermission(entry.getResourceClassName(), null, name,
1064         "getClassLoaderFor");
1065      
1066      ClassLoader JavaDoc cl = entry.getClassLoader();
1067      if (cl == null)
1068         cl = entry.getResourceInstance().getClass().getClassLoader();
1069      if (cl == null)
1070         cl = ClassLoader.getSystemClassLoader();
1071      return cl;
1072   }
1073
1074   /**
1075    *
1076    * @param name The ObjectName of the ClassLoader. May be null, in which case
1077    * the MBean server's own ClassLoader is returned.
1078    * @return
1079    * @throws InstanceNotFoundException
1080    */

1081   public ClassLoader JavaDoc getClassLoader(ObjectName JavaDoc name)
1082           throws InstanceNotFoundException JavaDoc
1083   {
1084      Object JavaDoc loader = null;
1085      if( name == null )
1086      {
1087         checkMBeanPermission(null, null, name, "getClassLoader");
1088         loader = getClass().getClassLoader();
1089         if (loader == null)
1090            loader = ClassLoader.getSystemClassLoader();
1091      }
1092      else
1093      {
1094         MBeanEntry entry = registry.get(name);
1095         checkMBeanPermission(entry.getResourceClassName(), null, name,
1096            "getClassLoader");
1097         loader = entry.getResourceInstance();
1098      }
1099
1100      if ((loader instanceof ClassLoader JavaDoc) == false)
1101         throw new InstanceNotFoundException JavaDoc("Not a classloader " + name);
1102      return (ClassLoader JavaDoc) loader;
1103   }
1104
1105   /**
1106    * Retrieve the classloader repository for this mbean server
1107    *
1108    * @return the classloader repository
1109    */

1110   public ClassLoaderRepository JavaDoc getClassLoaderRepository()
1111   {
1112      checkMBeanPermission(null, null, null, "getClassLoaderRepository");
1113
1114      // we don't need to synchronize, because this is the first thing we do in the constructor
1115
if (classLoaderRepository == null)
1116      {
1117         ClassLoader JavaDoc cl = Thread.currentThread().getContextClassLoader();
1118         String JavaDoc className = PropertyAccess.getProperty(LOADER_REPOSITORY_CLASS_PROPERTY, DEFAULT_LOADER_REPOSITORY_CLASS);
1119         PropertyAccess.setProperty(LOADER_REPOSITORY_CLASS_PROPERTY, className);
1120
1121         try
1122         {
1123            Class JavaDoc repository = cl.loadClass(className);
1124            classLoaderRepository = (LoaderRepository JavaDoc) repository.newInstance();
1125         }
1126         catch (ClassNotFoundException JavaDoc e)
1127         {
1128            throw new Error JavaDoc("Cannot instantiate loader repository class: " + className);
1129         }
1130         catch (ClassCastException JavaDoc e)
1131         {
1132            throw new Error JavaDoc("Loader repository is not an instance of LoaderRepository: " + className);
1133         }
1134         catch (Exception JavaDoc e)
1135         {
1136            throw new Error JavaDoc("Error creating loader repository: " + e);
1137         }
1138      }
1139
1140      return classLoaderRepository;
1141   }
1142
1143
1144   public void releaseServer()
1145   {
1146      // shutdown the loader repository
1147
// try
1148
// {
1149
// invoke(new ObjectName(DEFAULT_LOADER_NAME),
1150
// "releaseLoaderRepository",
1151
// new Object[0],
1152
// new String[0] );
1153
// }
1154
// catch (Exception e)
1155
// {
1156
// log.error("Unable to shutdown loader repository");
1157
// e.printStackTrace();
1158
// }
1159

1160      registry.releaseRegistry();
1161      listeners.removeAll();
1162      listeners = null;
1163      registry = null;
1164   }
1165
1166
1167   // Protected -----------------------------------------------------
1168

1169   /**
1170    * Instantiate an object, the passed classloader is set as the
1171    * thread's context classloader for the duration of this method.
1172    *
1173    * @param className the class name of the object to instantiate
1174    * @param cl the thread classloader, pass null to use the ClassLoaderRepository
1175    * @param params the parameters for the constructor
1176    * @param signature the signature of the constructor
1177    * @exception ReflectionException wraps a ClassCastException or
1178    * any Exception trying to invoke the constructor
1179    * @exception MBeanException wraps any exception thrown by the constructor
1180    * @exception RuntimeOperationsException Wraps an IllegalArgument for a
1181    * null className
1182    */

1183   protected Object JavaDoc instantiate(String JavaDoc className, ClassLoader JavaDoc cl, Object JavaDoc[] params, String JavaDoc[] signature)
1184           throws ReflectionException JavaDoc, MBeanException JavaDoc
1185   {
1186      if (className == null)
1187         throw new RuntimeOperationsException JavaDoc(new IllegalArgumentException JavaDoc("Null className"));
1188
1189      if (className.equals(""))
1190         throw new ReflectionException JavaDoc(new ClassNotFoundException JavaDoc("empty class name"));
1191
1192      if (params == null)
1193         params = NOPARAMS;
1194
1195      if (signature == null)
1196         signature = NOSIG;
1197
1198      checkMBeanPermission(className, null, null, "instantiate");
1199
1200      ClassLoader JavaDoc oldTCL = TCLAction.UTIL.getContextClassLoader();
1201
1202      boolean setCl = false;
1203      try
1204      {
1205         Class JavaDoc clazz = null;
1206         if (cl != null)
1207         {
1208            if (cl != oldTCL)
1209            {
1210               setCl = true;
1211               TCLAction.UTIL.setContextClassLoader(cl);
1212            }
1213            clazz = cl.loadClass(className);
1214         }
1215         else
1216            clazz = classLoaderRepository.loadClass(className);
1217
1218         Class JavaDoc[] sign = new Class JavaDoc[signature.length];
1219         for (int i = 0; i < signature.length; ++i)
1220         {
1221            if (LoaderRepository.getNativeClassForName(signature[i]) == null)
1222            {
1223               try
1224               {
1225                  if (cl != null)
1226                     sign[i] = cl.loadClass(signature[i]);
1227                  else
1228                     sign[i] = classLoaderRepository.loadClass(signature[i]);
1229               }
1230               catch (ClassNotFoundException JavaDoc e)
1231               {
1232                  throw new ReflectionException JavaDoc(e, "Constructor parameter class not found: " + signature[i]);
1233               }
1234            }
1235            else
1236            {
1237               sign[i] = LoaderRepository.getNativeClassForName(signature[i]);
1238            }
1239         }
1240
1241         Constructor JavaDoc constructor = clazz.getConstructor(sign);
1242         return constructor.newInstance(params);
1243      }
1244      catch (Throwable JavaDoc t)
1245      {
1246         handleInstantiateExceptions(t, className);
1247         log.error("Unhandled exception instantiating class: " + className, t);
1248         return null;
1249      }
1250      finally
1251      {
1252         if (setCl)
1253            TCLAction.UTIL.setContextClassLoader(oldTCL);
1254      }
1255   }
1256
1257   /**
1258    * Handles errors thrown during class instantiation
1259    */

1260   protected void handleInstantiateExceptions(Throwable JavaDoc t, String JavaDoc className)
1261           throws ReflectionException JavaDoc, MBeanException JavaDoc
1262   {
1263      if (t instanceof ReflectionException JavaDoc)
1264         throw (ReflectionException JavaDoc) t;
1265
1266      else if (t instanceof ClassNotFoundException JavaDoc)
1267         throw new ReflectionException JavaDoc((Exception JavaDoc) t, "Class not found: " + className);
1268
1269      else if (t instanceof InstantiationException JavaDoc)
1270         throw new ReflectionException JavaDoc((Exception JavaDoc) t, "Cannot instantiate: " + className);
1271
1272      else if (t instanceof IllegalAccessException JavaDoc)
1273         throw new ReflectionException JavaDoc((Exception JavaDoc) t, "Illegal access to constructor: " + className);
1274
1275      else if (t instanceof NoSuchMethodException JavaDoc)
1276         throw new ReflectionException JavaDoc((Exception JavaDoc) t, "Cannot find such a public constructor: " + className);
1277
1278      else if (t instanceof SecurityException JavaDoc)
1279         throw new ReflectionException JavaDoc((Exception JavaDoc) t, "Can't access constructor for " + className);
1280
1281      else if (t instanceof InvocationTargetException JavaDoc)
1282      {
1283         Throwable JavaDoc root = ((InvocationTargetException JavaDoc) t).getTargetException();
1284
1285         if (root instanceof RuntimeException JavaDoc)
1286            throw new RuntimeMBeanException JavaDoc((RuntimeException JavaDoc) root, className + " constructor has thrown an exception: " + root.toString());
1287         else if (root instanceof Error JavaDoc)
1288            throw new RuntimeErrorException JavaDoc((Error JavaDoc) root, className + " constructor has thrown an error: " + root.toString());
1289         else if (root instanceof Exception JavaDoc)
1290            throw new MBeanException JavaDoc((Exception JavaDoc) root, className + " constructor has thrown an exception: " + root.toString());
1291
1292         throw new Error JavaDoc("Something went wrong with handling the exception from " + className + " default constructor.");
1293      }
1294
1295      else if (t instanceof ExceptionInInitializerError JavaDoc)
1296      {
1297         Throwable JavaDoc root = ((ExceptionInInitializerError JavaDoc) t).getException();
1298
1299         // the root cause can be only a runtime exception
1300
if (root instanceof RuntimeException JavaDoc)
1301            throw new RuntimeMBeanException JavaDoc((RuntimeException JavaDoc) root, "Exception in class " + className + " static initializer: " + root.toString());
1302         else
1303         // shouldn't get here
1304
throw new Error JavaDoc("ERROR: it turns out the root cause is not always a runtime exception!");
1305      }
1306
1307      else if (t instanceof IllegalArgumentException JavaDoc)
1308      {
1309         // if mismatch between constructor instance args and supplied args -- shouldn't happen
1310
throw new Error JavaDoc("Error in the server: mismatch between expected constructor arguments and supplied arguments.");
1311      }
1312
1313      else if (t instanceof Error JavaDoc)
1314      {
1315         throw new RuntimeErrorException JavaDoc((Error JavaDoc) t, "instantiating " + className + " failed: " + t.toString());
1316      }
1317   }
1318
1319
1320   /**
1321    * Register an MBean<p>
1322    *
1323    * The classloader is used as the thread context classloader during
1324    * access to the mbean and it's interceptors
1325    *
1326    * @param mbean the mbean to register
1327    * @param name the object name to register
1328    * @param loaderName the object name of a class loader also used as
1329    * as the MBeans TCL
1330    * @exception InstanceAlreadyExistsException when already registered
1331    * @exception MBeanRegistrationException when
1332    * preRegister(MBeanServer, ObjectName) throws an exception
1333    * @exception NotCompliantMBeanException when the object is not an MBean
1334    */

1335   protected ObjectInstance JavaDoc registerMBean(Object JavaDoc mbean, ObjectName JavaDoc name, ObjectName JavaDoc loaderName)
1336           throws ReflectionException JavaDoc, InstanceAlreadyExistsException JavaDoc, MBeanRegistrationException JavaDoc, MBeanException JavaDoc, NotCompliantMBeanException JavaDoc, InstanceNotFoundException JavaDoc
1337   {
1338      ClassLoader JavaDoc cl = null;
1339
1340      // If the loader name is null, the ClassLoader that loaded the MBean Server will be used.
1341
if (loaderName == null)
1342      {
1343         cl = getClass().getClassLoader();
1344         if (cl == null)
1345            cl = ClassLoader.getSystemClassLoader();
1346      }
1347      else
1348      {
1349         try
1350         {
1351            cl = (ClassLoader JavaDoc) registry.get(loaderName).getResourceInstance();
1352         }
1353         catch (ClassCastException JavaDoc e)
1354         {
1355            throw new ReflectionException JavaDoc(e, loaderName + " is not a class loader.");
1356         }
1357      }
1358
1359      return registerMBean(mbean, name, cl);
1360   }
1361
1362   /**
1363    * Register an MBean<p>
1364    *
1365    * The classloader is used as the thread context classloader during
1366    * access to the mbean and it's interceptors
1367    *
1368    * @param object the mbean to register
1369    * @param name the object name to register
1370    * @param cl the thread classloader, pass null for the current one
1371    * @exception InstanceAlreadyExistsException when already registered
1372    * @exception MBeanRegistrationException when
1373    * preRegister(MBeanServer, ObjectName) throws an exception
1374    * @exception NotCompliantMBeanException when the object is not an MBean
1375    */

1376   protected ObjectInstance JavaDoc registerMBean(Object JavaDoc object, ObjectName JavaDoc name,
1377                                          ClassLoader JavaDoc cl)
1378           throws InstanceAlreadyExistsException JavaDoc,
1379           MBeanRegistrationException JavaDoc,
1380           NotCompliantMBeanException JavaDoc
1381   {
1382      final Class JavaDoc objectClass = object.getClass();
1383      String JavaDoc className = objectClass.getName();
1384
1385      // Check that the caller has the ability to create/register mbeans
1386
checkMBeanPermission(className, null, name, "registerMBean");
1387
1388      // Check that the mbean class is from a trusted source
1389
if( System.getSecurityManager() != null )
1390      {
1391         ProtectionDomain JavaDoc pd = (ProtectionDomain JavaDoc) AccessController.doPrivileged(
1392            new PrivilegedAction JavaDoc()
1393            {
1394               public Object JavaDoc run()
1395               {
1396                  return objectClass.getProtectionDomain();
1397               }
1398            }
1399         );
1400         if( pd != null )
1401         {
1402            MBeanTrustPermission JavaDoc p = new MBeanTrustPermission JavaDoc("register");
1403            if( pd.implies(p) == false )
1404            {
1405               String JavaDoc msg = "MBeanTrustPermission(register) not implied by "
1406                  + "protection domain of mbean class: "+className+", pd: "+pd;
1407               throw new SecurityException JavaDoc(msg);
1408            }
1409         }
1410      }
1411
1412      HashMap JavaDoc valueMap = null;
1413      if (cl != null)
1414      {
1415         valueMap = new HashMap JavaDoc();
1416         valueMap.put(CLASSLOADER, cl);
1417      }
1418
1419      try
1420      {
1421         final Object JavaDoc[] args = {object, name, valueMap};
1422         final String JavaDoc[] sig = {Object JavaDoc.class.getName(),
1423            ObjectName JavaDoc.class.getName(), Map JavaDoc.class.getName()};
1424         try
1425         {
1426            ObjectInstance JavaDoc oi = (ObjectInstance JavaDoc) AccessController.doPrivileged(
1427               new PrivilegedExceptionAction JavaDoc()
1428               {
1429                  public Object JavaDoc run() throws Exception JavaDoc
1430                  {
1431                     return invoke(new ObjectName JavaDoc(MBEAN_REGISTRY),
1432                        "registerMBean", args, sig);
1433                  }
1434               }
1435            );
1436            return oi;
1437         }
1438         catch(PrivilegedActionException JavaDoc e)
1439         {
1440            throw e.getException();
1441         }
1442      }
1443      catch (Throwable JavaDoc t)
1444      {
1445         Throwable JavaDoc result = JMXExceptionDecoder.decodeToJMXException(t);
1446         if (result instanceof InstanceAlreadyExistsException JavaDoc)
1447            throw (InstanceAlreadyExistsException JavaDoc) result;
1448         if (result instanceof MBeanRegistrationException JavaDoc)
1449            throw (MBeanRegistrationException JavaDoc) result;
1450         if (result instanceof NotCompliantMBeanException JavaDoc)
1451            throw (NotCompliantMBeanException JavaDoc) result;
1452         if ( result instanceof JMRuntimeException JavaDoc )
1453            throw (JMRuntimeException JavaDoc) result;
1454         if (result instanceof MBeanException JavaDoc)
1455         {
1456            MBeanException JavaDoc e = (MBeanException JavaDoc) result;
1457            t = e.getTargetException();
1458            if (t instanceof InstanceAlreadyExistsException JavaDoc)
1459               throw (InstanceAlreadyExistsException JavaDoc) t;
1460            if (t instanceof MBeanRegistrationException JavaDoc)
1461               throw (MBeanRegistrationException JavaDoc) t;
1462            if (t instanceof NotCompliantMBeanException JavaDoc)
1463               throw (NotCompliantMBeanException JavaDoc) t;
1464         }
1465         if (result instanceof RuntimeException JavaDoc)
1466            throw new RuntimeMBeanException JavaDoc((RuntimeException JavaDoc) result);
1467         if (result instanceof Error JavaDoc)
1468            throw new RuntimeErrorException JavaDoc((Error JavaDoc) result);
1469
1470         // for some other reason, registration failed
1471
throw new MBeanRegistrationException JavaDoc(new InvocationTargetException JavaDoc(t), "Cannot register MBean");
1472      }
1473   }
1474
1475   // Private -------------------------------------------------------
1476

1477   /**
1478    * Query an MBean against the query
1479    *
1480    * @param objectName the object name of the mbean to check
1481    * @param queryExp the query expression to test
1482    * @return true when the query applies to the MBean or the query is null,
1483    * false otherwise.
1484    */

1485   protected boolean queryMBean(ObjectName JavaDoc objectName, QueryExp JavaDoc queryExp)
1486   {
1487      if (queryExp == null)
1488         return true;
1489
1490      try
1491      {
1492         return queryExp.apply(objectName);
1493      }
1494      catch (Exception JavaDoc e)
1495      {
1496         return false;
1497      }
1498   }
1499
1500
1501   protected MBeanRegistry createRegistry(String JavaDoc defaultDomain)
1502   {
1503      // Find the registry implementation class: can be configured via
1504
// MBEAN_REGISTRY_CLASS_PROPERTY by the client -- if not found use
1505
// the class defined in DEFAULT_MBEAN_REGISTRY_CLASS (see ServerConstants)
1506
String JavaDoc registryClass = PropertyAccess.getProperty(ServerConstants.MBEAN_REGISTRY_CLASS_PROPERTY,
1507              ServerConstants.DEFAULT_MBEAN_REGISTRY_CLASS);
1508
1509      try
1510      {
1511         // Try loading registry class via thread context classloader
1512
ClassLoader JavaDoc cl = Thread.currentThread().getContextClassLoader();
1513         Class JavaDoc clazz = cl.loadClass(registryClass);
1514
1515         // retrieve the constructor <init>(MBeanServer srvr, String defaultDomain, ClassLoaderRepository clr)
1516
Constructor JavaDoc constructor = clazz.getConstructor(new Class JavaDoc[] {MBeanServer JavaDoc.class, String JavaDoc.class, ClassLoaderRepository JavaDoc.class});
1517
1518         // instantiate registry
1519
return (MBeanRegistry) constructor.newInstance(new Object JavaDoc[] {outer, defaultDomain, classLoaderRepository});
1520      }
1521      // Any exception preventing the registry to be created will cause the agent to fail.
1522
// However, try to give detailed exception messages to indicate config errors.
1523
catch (ClassNotFoundException JavaDoc e)
1524      {
1525         throw new NestedRuntimeException("The MBean registry implementation class " + registryClass +
1526                 " was not found: ", e);
1527      }
1528      catch (NoSuchMethodException JavaDoc e)
1529      {
1530         throw new NestedRuntimeException("The MBean registry implementation class " + registryClass +
1531                 " must contain a default <init>(MBeanServer srvr, String domain) " +
1532                 " constructor.", e);
1533      }
1534      catch (InstantiationException JavaDoc e)
1535      {
1536         throw new NestedRuntimeException("Cannot instantiate class " + registryClass + ": ", e);
1537      }
1538      catch (IllegalAccessException JavaDoc e)
1539      {
1540         throw new NestedRuntimeException("Unable to create the MBean registry instance. Illegal access " +
1541                 "to class " + registryClass + " constructor: ", e);
1542      }
1543      catch (InvocationTargetException JavaDoc e)
1544      {
1545         throw new NestedRuntimeException("Unable to create the MBean registry instance. Class " + registryClass +
1546                 " has raised an exception in constructor: ", e.getTargetException());
1547      }
1548   }
1549
1550
1551   // Private -------------------------------------------------------
1552

1553   // FIXME: externalize this
1554
private ModelMBeanInfo JavaDoc getRegistryManagementInterface()
1555   {
1556      final boolean READABLE = true;
1557      final boolean WRITABLE = true;
1558      final boolean BOOLEAN = true;
1559
1560      // Default Domain attribute
1561
DescriptorSupport JavaDoc descDefaultDomain = new DescriptorSupport JavaDoc();
1562      descDefaultDomain.setField("name", "DefaultDomain");
1563      descDefaultDomain.setField("descriptorType", "attribute");
1564      descDefaultDomain.setField("displayName", "Default Domain");
1565      descDefaultDomain.setField("default", getDefaultDomain());
1566      descDefaultDomain.setField("currencyTimeLimit", "-1");
1567      ModelMBeanAttributeInfo JavaDoc defaultDomainInfo =
1568              new ModelMBeanAttributeInfo JavaDoc
1569                      ("DefaultDomain", String JavaDoc.class.getName(),
1570                              "The domain to use when an object name has no domain",
1571                              READABLE, !WRITABLE, !BOOLEAN,
1572                              descDefaultDomain);
1573
1574      // Size attribute
1575
DescriptorSupport JavaDoc descSize = new DescriptorSupport JavaDoc();
1576      descSize.setField("name", "Size");
1577      descSize.setField("descriptorType", "attribute");
1578      descSize.setField("displayName", "Size");
1579      descSize.setField("getMethod", "getSize");
1580      ModelMBeanAttributeInfo JavaDoc sizeInfo =
1581              new ModelMBeanAttributeInfo JavaDoc
1582                      ("Size", Integer.TYPE.getName(),
1583                              "The number of MBeans registered in the MBean Server",
1584                              READABLE, !WRITABLE, !BOOLEAN,
1585                              descSize);
1586
1587      // registerMBean operation
1588
DescriptorSupport JavaDoc descRegisterMBean = new DescriptorSupport JavaDoc();
1589      descRegisterMBean.setField("name", "registerMBean");
1590      descRegisterMBean.setField("descriptorType", "operation");
1591      descRegisterMBean.setField("role", "operation");
1592      MBeanParameterInfo JavaDoc[] registerMBeanParms =
1593              new MBeanParameterInfo JavaDoc[]
1594              {
1595                 new MBeanParameterInfo JavaDoc
1596                         ("Resource",
1597                                 Object JavaDoc.class.getName(),
1598                                 "A compliant MBean to be registered in the MBean Server"),
1599                 new MBeanParameterInfo JavaDoc
1600                         ("ObjectName",
1601                                 ObjectName JavaDoc.class.getName(),
1602                                 "The object name of the MBean"),
1603                 new MBeanParameterInfo JavaDoc
1604                         ("ValueMap",
1605                                 Map JavaDoc.class.getName(),
1606                                 "Values associated with the registration"),
1607              };
1608      ModelMBeanOperationInfo JavaDoc registerMBeanInfo =
1609              new ModelMBeanOperationInfo JavaDoc
1610                      ("registerMBean",
1611                              "Adds an MBean in the MBeanServer",
1612                              registerMBeanParms,
1613                              ObjectInstance JavaDoc.class.getName(),
1614                              ModelMBeanOperationInfo.ACTION_INFO,
1615                              descRegisterMBean);
1616
1617      // unregisterMBean operation
1618
DescriptorSupport JavaDoc descUnregisterMBean = new DescriptorSupport JavaDoc();
1619      descUnregisterMBean.setField("name", "unregisterMBean");
1620      descUnregisterMBean.setField("descriptorType", "operation");
1621      descUnregisterMBean.setField("role", "operation");
1622      MBeanParameterInfo JavaDoc[] unregisterMBeanParms =
1623              new MBeanParameterInfo JavaDoc[]
1624              {
1625                 new MBeanParameterInfo JavaDoc
1626                         ("ObjectName",
1627                                 ObjectName JavaDoc.class.getName(),
1628                                 "The object name of the MBean to remove")
1629              };
1630      ModelMBeanOperationInfo JavaDoc unregisterMBeanInfo =
1631              new ModelMBeanOperationInfo JavaDoc
1632                      ("unregisterMBean",
1633                              "Removes an MBean from the MBeanServer",
1634                              unregisterMBeanParms,
1635                              Void.TYPE.getName(),
1636                              ModelMBeanOperationInfo.ACTION,
1637                              descUnregisterMBean);
1638
1639      // getSize operation
1640
DescriptorSupport JavaDoc descGetSize = new DescriptorSupport JavaDoc();
1641      descGetSize.setField("name", "getSize");
1642      descGetSize.setField("descriptorType", "operation");
1643      descGetSize.setField("role", "getter");
1644      MBeanParameterInfo JavaDoc[] getSizeParms = new MBeanParameterInfo JavaDoc[0];
1645      ModelMBeanOperationInfo JavaDoc getSizeInfo =
1646              new ModelMBeanOperationInfo JavaDoc
1647                      ("getSize",
1648                              "Gets the number of MBeans registered",
1649                              getSizeParms,
1650                              Integer.TYPE.getName(),
1651                              ModelMBeanOperationInfo.INFO,
1652                              descGetSize);
1653
1654      // get operation
1655
DescriptorSupport JavaDoc descGet = new DescriptorSupport JavaDoc();
1656      descGet.setField("name", "get");
1657      descGet.setField("descriptorType", "operation");
1658      descGet.setField("role", "operation");
1659      MBeanParameterInfo JavaDoc[] getParam = new MBeanParameterInfo JavaDoc[1];
1660      getParam[0] = new MBeanParameterInfo JavaDoc("ObjectName", ObjectName JavaDoc.class.getName(), "object name to find");
1661      ModelMBeanOperationInfo JavaDoc getInfo =
1662              new ModelMBeanOperationInfo JavaDoc
1663                      ("get",
1664                              "Gets the MBeanEntry for a given ObjectName",
1665                              getParam,
1666                              MBeanEntry.class.getName(),
1667                              ModelMBeanOperationInfo.INFO,
1668                              descGet);
1669
1670      // getValue operation
1671
DescriptorSupport JavaDoc descGetValue = new DescriptorSupport JavaDoc();
1672      descGetValue.setField("name", "getValue");
1673      descGetValue.setField("descriptorType", "operation");
1674      descGetValue.setField("role", "operation");
1675      MBeanParameterInfo JavaDoc[] getValueParms = new MBeanParameterInfo JavaDoc[]
1676      {
1677         new MBeanParameterInfo JavaDoc
1678                 ("ObjectName",
1679                         ObjectName JavaDoc.class.getName(),
1680                         "The object name of the registered MBean"),
1681         new MBeanParameterInfo JavaDoc
1682                 ("Key",
1683                         String JavaDoc.class.getName(),
1684                         "The key to the value stored")
1685      };
1686      ModelMBeanOperationInfo JavaDoc getValueInfo =
1687              new ModelMBeanOperationInfo JavaDoc
1688                      ("getValue",
1689                              "Get a value stored in the MBean's registration",
1690                              getValueParms,
1691                              Object JavaDoc.class.getName(),
1692                              ModelMBeanOperationInfo.INFO,
1693                              descGetValue);
1694
1695      // Construct the modelmbean
1696
DescriptorSupport JavaDoc descMBean = new DescriptorSupport JavaDoc();
1697      descMBean.setField("name", RequiredModelMBeanInstantiator.getClassName());
1698      descMBean.setField("descriptorType", "MBean");
1699      descMBean.setField("displayName", "MBeanServer Registry");
1700      ModelMBeanAttributeInfo JavaDoc[] attrInfo = new ModelMBeanAttributeInfo JavaDoc[]
1701      {
1702         defaultDomainInfo,
1703         sizeInfo
1704      };
1705      ModelMBeanConstructorInfo JavaDoc[] ctorInfo = null;
1706      ModelMBeanOperationInfo JavaDoc[] opInfo = new ModelMBeanOperationInfo JavaDoc[]
1707      {
1708         registerMBeanInfo,
1709         unregisterMBeanInfo,
1710         getSizeInfo,
1711         getValueInfo,
1712         getInfo
1713      };
1714      ModelMBeanNotificationInfo JavaDoc[] notifyInfo = null;
1715      ModelMBeanInfoSupport JavaDoc info = new ModelMBeanInfoSupport JavaDoc
1716              (RequiredModelMBeanInstantiator.getClassName(),
1717                      "Managed Bean Registry",
1718                      attrInfo,
1719                      ctorInfo,
1720                      opInfo,
1721                      notifyInfo,
1722                      descMBean);
1723
1724      return info;
1725   }
1726
1727   private void checkMBeanPermission(String JavaDoc className, String JavaDoc member,
1728      ObjectName JavaDoc objectName, String JavaDoc action)
1729   {
1730      SecurityManager JavaDoc sm = System.getSecurityManager();
1731      if( sm != null )
1732      {
1733         MBeanPermission JavaDoc p = new MBeanPermission JavaDoc(className, member, objectName,
1734            action);
1735         sm.checkPermission(p);
1736      }
1737   }
1738   
1739   // Object overrides ----------------------------------------------
1740

1741   /**
1742    * Simple toString() revealing default domain
1743    */

1744   public String JavaDoc toString()
1745   {
1746      return super.toString() + "[ defaultDomain='" + this.getDefaultDomain() + "' ]";
1747   }
1748}
1749
Popular Tags