KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > mx4j > server > MBeanIntrospector


1 /*
2  * Copyright (C) The MX4J Contributors.
3  * All rights reserved.
4  *
5  * This software is distributed under the terms of the MX4J License version 1.0.
6  * See the terms of the MX4J License in the documentation provided with this software.
7  */

8
9 package mx4j.server;
10
11 import java.lang.reflect.Constructor JavaDoc;
12 import java.lang.reflect.Method JavaDoc;
13 import java.lang.reflect.Modifier JavaDoc;
14 import java.security.AccessController JavaDoc;
15 import java.security.PrivilegedAction JavaDoc;
16 import java.util.ArrayList JavaDoc;
17 import java.util.HashMap JavaDoc;
18 import java.util.WeakHashMap JavaDoc;
19 import javax.management.DynamicMBean JavaDoc;
20 import javax.management.MBeanAttributeInfo JavaDoc;
21 import javax.management.MBeanConstructorInfo JavaDoc;
22 import javax.management.MBeanInfo JavaDoc;
23 import javax.management.MBeanNotificationInfo JavaDoc;
24 import javax.management.MBeanOperationInfo JavaDoc;
25 import javax.management.MBeanParameterInfo JavaDoc;
26 import javax.management.NotificationBroadcaster JavaDoc;
27 import javax.management.loading.MLet JavaDoc;
28
29 import mx4j.MBeanDescription;
30 import mx4j.MBeanDescriptionAdapter;
31 import mx4j.MX4JSystemKeys;
32 import mx4j.log.Log;
33 import mx4j.log.Logger;
34 import mx4j.util.Utils;
35
36 /**
37  * Introspector for MBeans. <p>
38  * Main purposes of this class are:
39  * <ul>
40  * <li> Given an mbean, gather all information regarding it into a {@link MBeanMetaData} instance, see {@link #introspect}
41  * <li> Given an introspected MBeanMetaData, decide if the MBean is compliant or not.
42  * <li> Act as a factory for {@link MBeanInvoker}s
43  * </ul>
44  * <p/>
45  * The following system properties are used to control this class' behavior:
46  * <ul>
47  * <li> mx4j.strict.mbean.interface, if set to 'no' then are treated as standard MBeans also classes that implement
48  * management interfaces beloging to different packages or that are inner classes; otherwise are treated as MBeans
49  * only classes that implement interfaces whose name if the fully qualified name of the MBean class + "MBean"
50  * <li> mx4j.mbean.invoker, if set to the qualified name of an implementation of the {@link MBeanInvoker} interface,
51  * then an instance of the class will be used to invoke methods on standard MBeans. By default the generated-on-the-fly
52  * MBeanInvoker is used; to revert to the version that uses reflection, for example,
53  * use mx4j.mbean.invoker = {@link CachingReflectionMBeanInvoker mx4j.server.CachingReflectionMBeanInvoker}
54  * </ul>
55  *
56  * @version $Revision: 1.34 $
57  */

58 public class MBeanIntrospector
59 {
60    private static final MBeanDescriptionAdapter DEFAULT_DESCRIPTION = new MBeanDescriptionAdapter();
61    private static final MBeanConstructorInfo JavaDoc[] EMPTY_CONSTRUCTORS = new MBeanConstructorInfo JavaDoc[0];
62    private static final MBeanParameterInfo JavaDoc[] EMPTY_PARAMETERS = new MBeanParameterInfo JavaDoc[0];
63    private static final MBeanAttributeInfo JavaDoc[] EMPTY_ATTRIBUTES = new MBeanAttributeInfo JavaDoc[0];
64    private static final MBeanNotificationInfo JavaDoc[] EMPTY_NOTIFICATIONS = new MBeanNotificationInfo JavaDoc[0];
65    private static final MBeanOperationInfo JavaDoc[] EMPTY_OPERATIONS = new MBeanOperationInfo JavaDoc[0];
66
67    private boolean extendedMBeanInterfaces = false;
68    private boolean bcelAvailable = false;
69    private String JavaDoc mbeanInvokerClass = null;
70
71    private final WeakHashMap JavaDoc mbeanInfoCache = new WeakHashMap JavaDoc();
72    private final WeakHashMap JavaDoc mbeanInvokerCache = new WeakHashMap JavaDoc();
73
74    public MBeanIntrospector()
75    {
76       String JavaDoc strict = (String JavaDoc)AccessController.doPrivileged(new PrivilegedAction JavaDoc()
77       {
78          public Object JavaDoc run()
79          {
80             return System.getProperty(MX4JSystemKeys.MX4J_STRICT_MBEAN_INTERFACE);
81          }
82       });
83       if (strict != null && !Boolean.valueOf(strict).booleanValue())
84       {
85          extendedMBeanInterfaces = true;
86       }
87
88       // Try to see if BCEL classes are present
89
try
90       {
91          ClassLoader JavaDoc loader = getClass().getClassLoader();
92          if (loader == null) loader = Thread.currentThread().getContextClassLoader();
93          loader.loadClass("org.apache.bcelAvailable.generic.Type");
94          bcelAvailable = true;
95       }
96       catch (Throwable JavaDoc ignored)
97       {
98       }
99
100       // See if someone specified which MBean invoker to use
101
mbeanInvokerClass = (String JavaDoc)AccessController.doPrivileged(new PrivilegedAction JavaDoc()
102       {
103          public Object JavaDoc run()
104          {
105             return System.getProperty(MX4JSystemKeys.MX4J_MBEAN_INVOKER);
106          }
107       });
108    }
109
110    /**
111     * Introspect the given mbean, storing the results in the given metadata.
112     * It expects that the mbean field and the classloader field are not null
113     *
114     * @see #isMBeanCompliant
115     */

116    public void introspect(MBeanMetaData metadata)
117    {
118       introspectType(metadata);
119       introspectMBeanInfo(metadata);
120    }
121
122    /**
123     * Returns whether the given already introspected metadata is compliant.
124     * Must be called after {@link #introspect}
125     */

126    public boolean isMBeanCompliant(MBeanMetaData metadata)
127    {
128       return isMBeanClassCompliant(metadata) && isMBeanTypeCompliant(metadata) && isMBeanInfoCompliant(metadata);
129    }
130
131    /**
132     * Used by the test cases, invoked via reflection, keep it private.
133     * Introspect the mbean and returns if it's compliant
134     */

135    private boolean testCompliance(MBeanMetaData metadata)
136    {
137       introspect(metadata);
138       return isMBeanCompliant(metadata);
139    }
140
141    private boolean isMBeanClassCompliant(MBeanMetaData metadata)
142    {
143       // No requirements on the implementation (can be abstract, non public and no accessible constructors)
144
// but the management interface must be public
145
Logger logger = getLogger();
146       if (metadata.getMBeanInterface() != null)
147       {
148          boolean isPublic = Modifier.isPublic(metadata.getMBeanInterface().getModifiers());
149          if (!isPublic && logger.isEnabledFor(Logger.DEBUG)) logger.debug("MBean interface is not public");
150          return isPublic;
151       }
152       return true;
153    }
154
155    private boolean isMBeanTypeCompliant(MBeanMetaData metadata)
156    {
157       Logger logger = getLogger();
158
159       if (metadata.isMBeanStandard() && metadata.isMBeanDynamic())
160       {
161          if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("MBean is both standard and dynamic");
162          return false;
163       }
164       if (!metadata.isMBeanStandard() && !metadata.isMBeanDynamic())
165       {
166          if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("MBean is not standard nor dynamic");
167          return false;
168       }
169
170       return true;
171    }
172
173    private boolean isMBeanInfoCompliant(MBeanMetaData metadata)
174    {
175       Logger logger = getLogger();
176
177       MBeanInfo JavaDoc info = metadata.getMBeanInfo();
178       if (info == null)
179       {
180          if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("MBeanInfo is null");
181          return false;
182       }
183       if (info.getClassName() == null)
184       {
185          if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("MBeanInfo.getClassName() is null");
186          return false;
187       }
188       return true;
189    }
190
191    private void introspectType(MBeanMetaData metadata)
192    {
193       // Some information is already provided (StandardMBean)
194
if (metadata.isMBeanStandard())
195       {
196          introspectStandardMBean(metadata);
197          return;
198       }
199
200       if (metadata.getMBean() instanceof DynamicMBean JavaDoc)
201       {
202          metadata.setMBeanDynamic(true);
203          return;
204       }
205       else
206       {
207          metadata.setMBeanDynamic(false);
208          // Continue and see if it's a plain standard MBean
209
}
210
211       // We have a plain standard MBean, introspect it
212
introspectStandardMBean(metadata);
213    }
214
215    private void introspectStandardMBean(MBeanMetaData metadata)
216    {
217       Class JavaDoc management = metadata.getMBeanInterface();
218       if (management != null)
219       {
220          // Be sure the MBean implements the management interface
221
if (management.isInstance(metadata.getMBean()))
222          {
223             metadata.setMBeanInvoker(createInvoker(metadata));
224             return;
225          }
226          else
227          {
228             // Not compliant, reset the values
229
metadata.setMBeanStandard(false);
230             metadata.setMBeanInterface(null);
231             metadata.setMBeanInvoker(null);
232             return;
233          }
234       }
235       else
236       {
237          Class JavaDoc cls = metadata.getMBean().getClass();
238          for (Class JavaDoc c = cls; c != null; c = c.getSuperclass())
239          {
240             Class JavaDoc[] intfs = c.getInterfaces();
241             for (int i = 0; i < intfs.length; ++i)
242             {
243                Class JavaDoc intf = intfs[i];
244
245                if (implementsMBean(c.getName(), intf.getName()))
246                {
247                   // OK, found the MBean interface for this class
248
metadata.setMBeanStandard(true);
249                   metadata.setMBeanInterface(intf);
250                   metadata.setMBeanInvoker(createInvoker(metadata));
251                   return;
252                }
253             }
254          }
255
256          // Management interface not found, it's not compliant, reset the values
257
metadata.setMBeanStandard(false);
258          metadata.setMBeanInterface(null);
259          metadata.setMBeanInvoker(null);
260       }
261    }
262
263    private void introspectMBeanInfo(MBeanMetaData metadata)
264    {
265       if (metadata.isMBeanDynamic())
266       {
267          metadata.setMBeanInfo(getDynamicMBeanInfo(metadata));
268       }
269       else if (metadata.isMBeanStandard())
270       {
271          metadata.setMBeanInfo(createStandardMBeanInfo(metadata));
272       }
273       else
274       {
275          // Not a valid MBean, reset the MBeanInfo: this will cause an exception later
276
metadata.setMBeanInfo(null);
277       }
278    }
279
280    private MBeanInfo JavaDoc getDynamicMBeanInfo(MBeanMetaData metadata)
281    {
282       Logger logger = getLogger();
283
284       MBeanInfo JavaDoc info = null;
285
286       try
287       {
288          info = ((DynamicMBean JavaDoc)metadata.getMBean()).getMBeanInfo();
289       }
290       catch (Exception JavaDoc x)
291       {
292          if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("getMBeanInfo threw: " + x.toString());
293       }
294
295       if (logger.isEnabledFor(Logger.TRACE)) logger.trace("Dynamic MBeanInfo is: " + info);
296
297       if (info == null)
298       {
299          if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("MBeanInfo cannot be null");
300          return null;
301       }
302
303       return info;
304    }
305
306    private MBeanInfo JavaDoc createStandardMBeanInfo(MBeanMetaData metadata)
307    {
308       synchronized (mbeanInfoCache)
309       {
310          MBeanInfo JavaDoc info = (MBeanInfo JavaDoc)mbeanInfoCache.get(metadata.getMBean().getClass());
311          if (info != null) return info;
312       }
313
314       // This is a non-standard extension: description for standard MBeans
315
MBeanDescription description = createMBeanDescription(metadata);
316
317       MBeanConstructorInfo JavaDoc[] ctors = createMBeanConstructorInfo(metadata, description);
318       if (ctors == null) return null;
319       MBeanAttributeInfo JavaDoc[] attrs = createMBeanAttributeInfo(metadata, description);
320       if (attrs == null) return null;
321       MBeanOperationInfo JavaDoc[] opers = createMBeanOperationInfo(metadata, description);
322       if (opers == null) return null;
323       MBeanNotificationInfo JavaDoc[] notifs = createMBeanNotificationInfo(metadata);
324       if (notifs == null) return null;
325
326       MBeanInfo JavaDoc info = new MBeanInfo JavaDoc(metadata.getMBean().getClass().getName(), description.getMBeanDescription(), attrs, ctors, opers, notifs);
327       synchronized (mbeanInfoCache)
328       {
329          // Overwrite if already present, we've been unlucky
330
mbeanInfoCache.put(metadata.getMBean().getClass(), info);
331       }
332       return info;
333    }
334
335    private MBeanDescription createMBeanDescription(MBeanMetaData metadata)
336    {
337       // TODO: PERFORMANCE: looking up the MBeanDescription is a real performance hotspot for MBean registration
338
// TODO: PERFORMANCE: simply remarking the lookup yields to a 3.5x speedup (from 14 s to 4 s for 20k MBeans)
339
// TODO: PERFORMANCE: consider using a system property to disable lookup, and/or caching the lookup.
340

341       // This is a non-standard extension
342

343       Logger logger = getLogger();
344       if (logger.isEnabledFor(Logger.TRACE)) logger.trace("Looking for standard MBean description...");
345
346       // Use full qualified name only
347
String JavaDoc descrClassName = metadata.getMBeanInterface().getName() + "Description";
348       // Try to load the class
349
try
350       {
351          Class JavaDoc descrClass = null;
352          ClassLoader JavaDoc loader = metadata.getClassLoader();
353          if (loader == null) loader = Thread.currentThread().getContextClassLoader();
354          // Optimize lookup of the description class in case of MLets: we lookup the description class
355
// only in the classloader of the mbean, not in the whole CLR (since MLets delegates to the CLR)
356
if (loader.getClass() == MLet JavaDoc.class)
357             descrClass = ((MLet JavaDoc)loader).loadClass(descrClassName, null);
358          else
359             descrClass = loader.loadClass(descrClassName);
360
361          Object JavaDoc descrInstance = descrClass.newInstance();
362          if (descrInstance instanceof MBeanDescription)
363          {
364             MBeanDescription description = (MBeanDescription)descrInstance;
365             if (logger.isEnabledFor(Logger.TRACE)) logger.trace("Found provided standard MBean description: " + description);
366             return description;
367          }
368       }
369       catch (ClassNotFoundException JavaDoc ignored)
370       {
371       }
372       catch (InstantiationException JavaDoc ignored)
373       {
374       }
375       catch (IllegalAccessException JavaDoc ignored)
376       {
377       }
378
379       MBeanDescription description = DEFAULT_DESCRIPTION;
380       if (logger.isEnabledFor(Logger.TRACE)) logger.trace("Cannot find standard MBean description, using default: " + description);
381       return description;
382    }
383
384    private MBeanOperationInfo JavaDoc[] createMBeanOperationInfo(MBeanMetaData metadata, MBeanDescription description)
385    {
386       ArrayList JavaDoc operations = new ArrayList JavaDoc();
387
388       Method JavaDoc[] methods = metadata.getMBeanInterface().getMethods();
389       for (int j = 0; j < methods.length; ++j)
390       {
391          Method JavaDoc method = methods[j];
392          if (!Utils.isAttributeGetter(method) && !Utils.isAttributeSetter(method))
393          {
394             String JavaDoc descr = description == null ? null : description.getOperationDescription(method);
395             Class JavaDoc[] params = method.getParameterTypes();
396             int paramsNumber = params.length;
397             MBeanParameterInfo JavaDoc[] paramsInfo = paramsNumber == 0 ? EMPTY_PARAMETERS : new MBeanParameterInfo JavaDoc[paramsNumber];
398             for (int k = 0; k < paramsNumber; ++k)
399             {
400                Class JavaDoc param = params[k];
401                String JavaDoc paramName = description == null ? null : description.getOperationParameterName(method, k);
402                String JavaDoc paramDescr = description == null ? null : description.getOperationParameterDescription(method, k);
403                paramsInfo[k] = new MBeanParameterInfo JavaDoc(paramName, param.getName(), paramDescr);
404             }
405             MBeanOperationInfo JavaDoc info = new MBeanOperationInfo JavaDoc(method.getName(), descr, paramsInfo, method.getReturnType().getName(), MBeanOperationInfo.UNKNOWN);
406             operations.add(info);
407          }
408       }
409
410       int opersNumber = operations.size();
411       return opersNumber == 0 ? EMPTY_OPERATIONS : (MBeanOperationInfo JavaDoc[])operations.toArray(new MBeanOperationInfo JavaDoc[opersNumber]);
412    }
413
414    private MBeanAttributeInfo JavaDoc[] createMBeanAttributeInfo(MBeanMetaData metadata, MBeanDescription description)
415    {
416       Logger logger = getLogger();
417
418       HashMap JavaDoc attributes = new HashMap JavaDoc();
419       HashMap JavaDoc getterNames = new HashMap JavaDoc();
420
421       Method JavaDoc[] methods = metadata.getMBeanInterface().getMethods();
422       for (int j = 0; j < methods.length; ++j)
423       {
424          Method JavaDoc method = methods[j];
425          if (Utils.isAttributeGetter(method))
426          {
427             String JavaDoc name = method.getName();
428             boolean isIs = name.startsWith("is");
429
430             String JavaDoc attribute = null;
431             if (isIs)
432                attribute = name.substring(2);
433             else
434                attribute = name.substring(3);
435
436             String JavaDoc descr = description == null ? null : description.getAttributeDescription(attribute);
437
438             MBeanAttributeInfo JavaDoc info = (MBeanAttributeInfo JavaDoc)attributes.get(attribute);
439
440             if (info != null)
441             {
442                // JMX spec does not allow overloading attributes.
443
// If an attribute with the same name already exists the MBean is not compliant
444
if (!info.getType().equals(method.getReturnType().getName()))
445                {
446                   if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("MBean is not compliant: has overloaded attribute " + attribute);
447                   return null;
448                }
449                else
450                {
451                   // They return the same value,
452
if (getterNames.get(name) != null)
453                   {
454                      // This is the case of an attribute being present in multiple interfaces
455
// Ignore all but the first, since they resolve to the same method anyways
456
continue;
457                   }
458
459                   // there is a chance that one is a get-getter and one is a is-getter
460
// for a boolean attribute. In this case, the MBean is not compliant.
461
if (info.isReadable())
462                   {
463                      if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("MBean is not compliant: has overloaded attribute " + attribute);
464                      return null;
465                   }
466
467                   // MBeanAttributeInfo is already present due to a setter method, just update its readability
468
info = new MBeanAttributeInfo JavaDoc(attribute, info.getType(), info.getDescription(), true, info.isWritable(), isIs);
469                }
470             }
471             else
472             {
473                info = new MBeanAttributeInfo JavaDoc(attribute, method.getReturnType().getName(), descr, true, false, isIs);
474             }
475
476             // Replace if exists
477
attributes.put(attribute, info);
478             getterNames.put(name, method);
479          }
480          else if (Utils.isAttributeSetter(method))
481          {
482             String JavaDoc name = method.getName();
483             String JavaDoc attribute = name.substring(3);
484
485             String JavaDoc descr = description == null ? null : description.getAttributeDescription(attribute);
486
487             MBeanAttributeInfo JavaDoc info = (MBeanAttributeInfo JavaDoc)attributes.get(attribute);
488
489             if (info != null)
490             {
491                // JMX spec does not allow overloading attributes.
492
// If an attribute with the same name already exists the MBean is not compliant
493
if (!info.getType().equals(method.getParameterTypes()[0].getName()))
494                {
495                   if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("MBean is not compliant: has overloaded attribute " + attribute);
496                   return null;
497                }
498                else
499                {
500                   // MBeanAttributeInfo is already present due to a getter method, just update its writability
501
info = new MBeanAttributeInfo JavaDoc(info.getName(), info.getType(), info.getDescription(), info.isReadable(), true, info.isIs());
502                }
503             }
504             else
505             {
506                info = new MBeanAttributeInfo JavaDoc(attribute, method.getParameterTypes()[0].getName(), descr, false, true, false);
507             }
508
509             // Replace if exists
510
attributes.put(attribute, info);
511          }
512       }
513
514       int size = attributes.size();
515       return size == 0 ? EMPTY_ATTRIBUTES : (MBeanAttributeInfo JavaDoc[])attributes.values().toArray(new MBeanAttributeInfo JavaDoc[size]);
516    }
517
518    private MBeanNotificationInfo JavaDoc[] createMBeanNotificationInfo(MBeanMetaData metadata)
519    {
520       MBeanNotificationInfo JavaDoc[] notifs = null;
521       Object JavaDoc mbean = metadata.getMBean();
522       if (mbean instanceof NotificationBroadcaster JavaDoc)
523       {
524          notifs = ((NotificationBroadcaster JavaDoc)mbean).getNotificationInfo();
525       }
526       if (notifs == null || notifs.length == 0) notifs = EMPTY_NOTIFICATIONS;
527       return notifs;
528    }
529
530    private MBeanConstructorInfo JavaDoc[] createMBeanConstructorInfo(MBeanMetaData metadata, MBeanDescription descrs)
531    {
532       Class JavaDoc mbeanClass = metadata.getMBean().getClass();
533
534       Constructor JavaDoc[] ctors = mbeanClass.getConstructors();
535
536       int ctorsNumber = ctors.length;
537       MBeanConstructorInfo JavaDoc[] constructors = ctorsNumber == 0 ? EMPTY_CONSTRUCTORS : new MBeanConstructorInfo JavaDoc[ctorsNumber];
538       for (int i = 0; i < ctorsNumber; ++i)
539       {
540          Constructor JavaDoc constructor = ctors[i];
541          String JavaDoc descr = descrs == null ? null : descrs.getConstructorDescription(constructor);
542          Class JavaDoc[] params = constructor.getParameterTypes();
543          int paramsNumber = params.length;
544          MBeanParameterInfo JavaDoc[] paramsInfo = paramsNumber == 0 ? EMPTY_PARAMETERS : new MBeanParameterInfo JavaDoc[paramsNumber];
545          for (int j = 0; j < paramsNumber; ++j)
546          {
547             Class JavaDoc param = params[j];
548             String JavaDoc paramName = descrs == null ? null : descrs.getConstructorParameterName(constructor, j);
549             String JavaDoc paramDescr = descrs == null ? null : descrs.getConstructorParameterDescription(constructor, j);
550             paramsInfo[j] = new MBeanParameterInfo JavaDoc(paramName, param.getName(), paramDescr);
551          }
552
553          String JavaDoc ctorName = constructor.getName();
554          MBeanConstructorInfo JavaDoc info = new MBeanConstructorInfo JavaDoc(ctorName, descr, paramsInfo);
555          constructors[i] = info;
556       }
557       return constructors;
558    }
559
560    private boolean implementsMBean(String JavaDoc clsName, String JavaDoc intfName)
561    {
562       if (intfName.equals(clsName + "MBean")) return true;
563
564       if (extendedMBeanInterfaces)
565       {
566          // Check also that the may be in different packages and/or inner classes
567

568          // Trim packages
569
int clsDot = clsName.lastIndexOf('.');
570          if (clsDot > 0) clsName = clsName.substring(clsDot + 1);
571          int intfDot = intfName.lastIndexOf('.');
572          if (intfDot > 0) intfName = intfName.substring(intfDot + 1);
573          // Try again
574
if (intfName.equals(clsName + "MBean")) return true;
575
576          // Trim inner classes
577
int clsDollar = clsName.lastIndexOf('$');
578          if (clsDollar > 0) clsName = clsName.substring(clsDollar + 1);
579          int intfDollar = intfName.lastIndexOf('$');
580          if (intfDollar > 0) intfName = intfName.substring(intfDollar + 1);
581          // Try again
582
if (intfName.equals(clsName + "MBean")) return true;
583       }
584
585       // Give up
586
return false;
587    }
588
589    private MBeanInvoker createInvoker(MBeanMetaData metadata)
590    {
591       MBeanInvoker invoker = null;
592
593       synchronized (mbeanInvokerCache)
594       {
595          invoker = (MBeanInvoker)mbeanInvokerCache.get(metadata.getMBeanInterface());
596          if (invoker != null) return invoker;
597       }
598
599       Logger logger = getLogger();
600
601       if (mbeanInvokerClass != null)
602       {
603          if (logger.isEnabledFor(Logger.TRACE)) logger.trace("Custom MBeanInvoker class is: " + mbeanInvokerClass);
604          try
605          {
606             invoker = (MBeanInvoker)Thread.currentThread().getContextClassLoader().loadClass(mbeanInvokerClass).newInstance();
607             if (logger.isEnabledFor(Logger.TRACE)) logger.trace("Using custom MBeanInvoker: " + invoker);
608          }
609          catch (Exception JavaDoc x)
610          {
611             if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("Cannot instantiate custom MBeanInvoker, using default", x);
612          }
613       }
614
615       if (invoker == null)
616       {
617          if (bcelAvailable)
618          {
619             invoker = BCELMBeanInvoker.create(metadata);
620             if (logger.isEnabledFor(Logger.TRACE)) logger.trace("Using default BCEL MBeanInvoker for MBean " + metadata.getObjectName() + ", " + invoker);
621          }
622          else
623          {
624             invoker = new CachingReflectionMBeanInvoker();
625             if (logger.isEnabledFor(Logger.TRACE)) logger.trace("Using default Reflection MBeanInvoker for MBean " + metadata.getObjectName() + ", " + invoker);
626          }
627       }
628
629       synchronized (mbeanInvokerCache)
630       {
631          // Overwrite if already present: we've been unlucky
632
mbeanInvokerCache.put(metadata.getMBeanInterface(), invoker);
633       }
634       return invoker;
635    }
636
637    private Logger getLogger()
638    {
639       return Log.getLogger(getClass().getName());
640    }
641 }
642
Popular Tags