changeset 4156 | acaa49a2768a |
parent 1700 | 4506662fb2ee |
child 5506 | 202f599c92aa |
4155:460e37d40f12 | 4156:acaa49a2768a |
---|---|
28 |
28 |
29 // JMX RI |
29 // JMX RI |
30 import static com.sun.jmx.defaults.JmxProperties.MBEANSERVER_LOGGER; |
30 import static com.sun.jmx.defaults.JmxProperties.MBEANSERVER_LOGGER; |
31 import com.sun.jmx.mbeanserver.DynamicMBean2; |
31 import com.sun.jmx.mbeanserver.DynamicMBean2; |
32 import com.sun.jmx.mbeanserver.Introspector; |
32 import com.sun.jmx.mbeanserver.Introspector; |
33 import com.sun.jmx.mbeanserver.MBeanInjector; |
|
34 import com.sun.jmx.mbeanserver.MBeanInstantiator; |
33 import com.sun.jmx.mbeanserver.MBeanInstantiator; |
35 import com.sun.jmx.mbeanserver.ModifiableClassLoaderRepository; |
34 import com.sun.jmx.mbeanserver.ModifiableClassLoaderRepository; |
36 import com.sun.jmx.mbeanserver.NamedObject; |
35 import com.sun.jmx.mbeanserver.NamedObject; |
37 import com.sun.jmx.mbeanserver.NotifySupport; |
|
38 import com.sun.jmx.mbeanserver.Repository; |
36 import com.sun.jmx.mbeanserver.Repository; |
39 import com.sun.jmx.mbeanserver.Repository.RegistrationContext; |
37 import com.sun.jmx.mbeanserver.Repository.RegistrationContext; |
40 import com.sun.jmx.mbeanserver.Util; |
38 import com.sun.jmx.mbeanserver.Util; |
41 import com.sun.jmx.remote.util.EnvHelp; |
39 import com.sun.jmx.remote.util.EnvHelp; |
42 |
40 |
41 import java.io.ObjectInputStream; |
|
43 import java.lang.ref.WeakReference; |
42 import java.lang.ref.WeakReference; |
44 import java.security.AccessControlContext; |
43 import java.security.AccessControlContext; |
45 import java.security.AccessController; |
44 import java.security.AccessController; |
46 import java.security.Permission; |
45 import java.security.Permission; |
47 import java.security.PrivilegedAction; |
46 import java.security.PrivilegedAction; |
48 import java.security.ProtectionDomain; |
47 import java.security.ProtectionDomain; |
49 import java.util.ArrayList; |
48 import java.util.ArrayList; |
50 import java.util.HashSet; |
49 import java.util.HashSet; |
51 import java.util.Iterator; |
|
52 import java.util.LinkedList; |
|
53 import java.util.List; |
50 import java.util.List; |
54 import java.util.Queue; |
|
55 import java.util.Set; |
51 import java.util.Set; |
56 import java.util.WeakHashMap; |
52 import java.util.WeakHashMap; |
57 import java.util.logging.Level; |
53 import java.util.logging.Level; |
58 |
54 |
59 // JMX import |
55 // JMX import |
60 import javax.management.Attribute; |
56 import javax.management.Attribute; |
61 import javax.management.AttributeList; |
57 import javax.management.AttributeList; |
62 import javax.management.AttributeNotFoundException; |
58 import javax.management.AttributeNotFoundException; |
63 import javax.management.DynamicMBean; |
59 import javax.management.DynamicMBean; |
64 import javax.management.DynamicWrapperMBean; |
|
65 import javax.management.InstanceAlreadyExistsException; |
60 import javax.management.InstanceAlreadyExistsException; |
66 import javax.management.InstanceNotFoundException; |
61 import javax.management.InstanceNotFoundException; |
67 import javax.management.IntrospectionException; |
62 import javax.management.IntrospectionException; |
68 import javax.management.InvalidAttributeValueException; |
63 import javax.management.InvalidAttributeValueException; |
69 import javax.management.JMRuntimeException; |
64 import javax.management.JMRuntimeException; |
70 import javax.management.ListenerNotFoundException; |
65 import javax.management.ListenerNotFoundException; |
71 import javax.management.MBeanException; |
66 import javax.management.MBeanException; |
72 import javax.management.MBeanInfo; |
67 import javax.management.MBeanInfo; |
73 import javax.management.MBeanNotificationInfo; |
|
74 import javax.management.MBeanPermission; |
68 import javax.management.MBeanPermission; |
75 import javax.management.MBeanRegistration; |
69 import javax.management.MBeanRegistration; |
76 import javax.management.MBeanRegistrationException; |
70 import javax.management.MBeanRegistrationException; |
77 import javax.management.MBeanServer; |
71 import javax.management.MBeanServer; |
78 import javax.management.MBeanServerDelegate; |
72 import javax.management.MBeanServerDelegate; |
79 import javax.management.MBeanServerNotification; |
73 import javax.management.MBeanServerNotification; |
80 import javax.management.MBeanTrustPermission; |
74 import javax.management.MBeanTrustPermission; |
81 import javax.management.NotCompliantMBeanException; |
75 import javax.management.NotCompliantMBeanException; |
82 import javax.management.Notification; |
76 import javax.management.Notification; |
83 import javax.management.NotificationBroadcaster; |
77 import javax.management.NotificationBroadcaster; |
84 import javax.management.NotificationBroadcasterSupport; |
|
85 import javax.management.NotificationEmitter; |
78 import javax.management.NotificationEmitter; |
86 import javax.management.NotificationFilter; |
79 import javax.management.NotificationFilter; |
87 import javax.management.NotificationListener; |
80 import javax.management.NotificationListener; |
88 import javax.management.ObjectInstance; |
81 import javax.management.ObjectInstance; |
89 import javax.management.ObjectName; |
82 import javax.management.ObjectName; |
83 import javax.management.OperationsException; |
|
90 import javax.management.QueryEval; |
84 import javax.management.QueryEval; |
91 import javax.management.QueryExp; |
85 import javax.management.QueryExp; |
92 import javax.management.ReflectionException; |
86 import javax.management.ReflectionException; |
93 import javax.management.RuntimeErrorException; |
87 import javax.management.RuntimeErrorException; |
94 import javax.management.RuntimeMBeanException; |
88 import javax.management.RuntimeMBeanException; |
95 import javax.management.RuntimeOperationsException; |
89 import javax.management.RuntimeOperationsException; |
96 import javax.management.namespace.JMXNamespace; |
90 import javax.management.loading.ClassLoaderRepository; |
97 |
91 |
98 /** |
92 /** |
99 * This is the default class for MBean manipulation on the agent side. It |
93 * This is the default class for MBean manipulation on the agent side. It |
100 * contains the methods necessary for the creation, registration, and |
94 * contains the methods necessary for the creation, registration, and |
101 * deletion of MBeans as well as the access methods for registered MBeans. |
95 * deletion of MBeans as well as the access methods for registered MBeans. |
114 * <BR> |
108 * <BR> |
115 * <CODE>JMImplementation:type=MBeanServerDelegate</CODE>. |
109 * <CODE>JMImplementation:type=MBeanServerDelegate</CODE>. |
116 * |
110 * |
117 * @since 1.5 |
111 * @since 1.5 |
118 */ |
112 */ |
119 public class DefaultMBeanServerInterceptor |
113 public class DefaultMBeanServerInterceptor implements MBeanServerInterceptor { |
120 extends MBeanServerInterceptorSupport { |
|
121 |
114 |
122 /** The MBeanInstantiator object used by the |
115 /** The MBeanInstantiator object used by the |
123 * DefaultMBeanServerInterceptor */ |
116 * DefaultMBeanServerInterceptor */ |
124 private final transient MBeanInstantiator instantiator; |
117 private final transient MBeanInstantiator instantiator; |
125 |
118 |
140 WeakHashMap<ListenerWrapper, WeakReference<ListenerWrapper>> |
133 WeakHashMap<ListenerWrapper, WeakReference<ListenerWrapper>> |
141 listenerWrappers = |
134 listenerWrappers = |
142 new WeakHashMap<ListenerWrapper, |
135 new WeakHashMap<ListenerWrapper, |
143 WeakReference<ListenerWrapper>>(); |
136 WeakReference<ListenerWrapper>>(); |
144 |
137 |
145 private final NamespaceDispatchInterceptor dispatcher; |
|
146 |
|
147 /** The default domain of the object names */ |
138 /** The default domain of the object names */ |
148 private final String domain; |
139 private final String domain; |
149 |
|
150 /** The mbeanServerName */ |
|
151 private final String mbeanServerName; |
|
152 |
140 |
153 /** The sequence number identifying the notifications sent */ |
141 /** The sequence number identifying the notifications sent */ |
154 // Now sequence number is handled by MBeanServerDelegate. |
142 // Now sequence number is handled by MBeanServerDelegate. |
155 // private int sequenceNumber=0; |
143 // private int sequenceNumber=0; |
156 |
144 |
166 * with the new MBeanServer. The new MBeanServer must register |
154 * with the new MBeanServer. The new MBeanServer must register |
167 * this MBean in its MBean repository. |
155 * this MBean in its MBean repository. |
168 * @param instantiator The MBeanInstantiator that will be used to |
156 * @param instantiator The MBeanInstantiator that will be used to |
169 * instantiate MBeans and take care of class loading issues. |
157 * instantiate MBeans and take care of class loading issues. |
170 * @param repository The repository to use for this MBeanServer. |
158 * @param repository The repository to use for this MBeanServer. |
171 * @param dispatcher The dispatcher used by this MBeanServer |
|
172 */ |
159 */ |
173 public DefaultMBeanServerInterceptor(MBeanServer outer, |
160 public DefaultMBeanServerInterceptor(MBeanServer outer, |
174 MBeanServerDelegate delegate, |
161 MBeanServerDelegate delegate, |
175 MBeanInstantiator instantiator, |
162 MBeanInstantiator instantiator, |
176 Repository repository, |
163 Repository repository) { |
177 NamespaceDispatchInterceptor dispatcher) { |
|
178 if (outer == null) throw new |
164 if (outer == null) throw new |
179 IllegalArgumentException("outer MBeanServer cannot be null"); |
165 IllegalArgumentException("outer MBeanServer cannot be null"); |
180 if (delegate == null) throw new |
166 if (delegate == null) throw new |
181 IllegalArgumentException("MBeanServerDelegate cannot be null"); |
167 IllegalArgumentException("MBeanServerDelegate cannot be null"); |
182 if (instantiator == null) throw new |
168 if (instantiator == null) throw new |
187 this.server = outer; |
173 this.server = outer; |
188 this.delegate = delegate; |
174 this.delegate = delegate; |
189 this.instantiator = instantiator; |
175 this.instantiator = instantiator; |
190 this.repository = repository; |
176 this.repository = repository; |
191 this.domain = repository.getDefaultDomain(); |
177 this.domain = repository.getDefaultDomain(); |
192 this.dispatcher = dispatcher; |
|
193 this.mbeanServerName = Util.getMBeanServerSecurityName(delegate); |
|
194 } |
178 } |
195 |
179 |
196 public ObjectInstance createMBean(String className, ObjectName name) |
180 public ObjectInstance createMBean(String className, ObjectName name) |
197 throws ReflectionException, InstanceAlreadyExistsException, |
181 throws ReflectionException, InstanceAlreadyExistsException, |
198 MBeanRegistrationException, MBeanException, |
182 MBeanRegistrationException, MBeanException, |
267 } |
251 } |
268 |
252 |
269 name = nonDefaultDomain(name); |
253 name = nonDefaultDomain(name); |
270 } |
254 } |
271 |
255 |
272 checkMBeanPermission(mbeanServerName,className, null, null, "instantiate"); |
256 checkMBeanPermission(className, null, null, "instantiate"); |
273 checkMBeanPermission(mbeanServerName,className, null, name, "registerMBean"); |
257 checkMBeanPermission(className, null, name, "registerMBean"); |
274 |
258 |
275 /* Load the appropriate class. */ |
259 /* Load the appropriate class. */ |
276 if (withDefaultLoaderRepository) { |
260 if (withDefaultLoaderRepository) { |
277 if (MBEANSERVER_LOGGER.isLoggable(Level.FINER)) { |
261 if (MBEANSERVER_LOGGER.isLoggable(Level.FINER)) { |
278 MBEANSERVER_LOGGER.logp(Level.FINER, |
262 MBEANSERVER_LOGGER.logp(Level.FINER, |
332 |
316 |
333 Introspector.checkCompliance(theClass); |
317 Introspector.checkCompliance(theClass); |
334 |
318 |
335 final String infoClassName = getNewMBeanClassName(object); |
319 final String infoClassName = getNewMBeanClassName(object); |
336 |
320 |
337 checkMBeanPermission(mbeanServerName,infoClassName, null, name, "registerMBean"); |
321 checkMBeanPermission(infoClassName, null, name, "registerMBean"); |
338 checkMBeanTrustPermission(theClass); |
322 checkMBeanTrustPermission(theClass); |
339 |
323 |
340 return registerObject(infoClassName, object, name); |
324 return registerObject(infoClassName, object, name); |
341 } |
325 } |
342 |
326 |
441 throws InstanceNotFoundException, MBeanRegistrationException { |
425 throws InstanceNotFoundException, MBeanRegistrationException { |
442 |
426 |
443 DynamicMBean instance = getMBean(name); |
427 DynamicMBean instance = getMBean(name); |
444 // may throw InstanceNotFoundException |
428 // may throw InstanceNotFoundException |
445 |
429 |
446 checkMBeanPermission(mbeanServerName, instance, null, name, |
430 checkMBeanPermission(instance, null, name, "unregisterMBean"); |
447 "unregisterMBean"); |
|
448 |
431 |
449 if (instance instanceof MBeanRegistration) |
432 if (instance instanceof MBeanRegistration) |
450 preDeregisterInvoke((MBeanRegistration) instance); |
433 preDeregisterInvoke((MBeanRegistration) instance); |
451 |
434 |
452 final Object resource = getResource(instance); |
435 final Object resource = getResource(instance); |
476 throws InstanceNotFoundException { |
459 throws InstanceNotFoundException { |
477 |
460 |
478 name = nonDefaultDomain(name); |
461 name = nonDefaultDomain(name); |
479 DynamicMBean instance = getMBean(name); |
462 DynamicMBean instance = getMBean(name); |
480 |
463 |
481 checkMBeanPermission(mbeanServerName, |
464 checkMBeanPermission(instance, null, name, "getObjectInstance"); |
482 instance, null, name, "getObjectInstance"); |
|
483 |
465 |
484 final String className = getClassName(instance); |
466 final String className = getClassName(instance); |
485 |
467 |
486 return new ObjectInstance(name, className); |
468 return new ObjectInstance(name, className); |
487 } |
469 } |
489 public Set<ObjectInstance> queryMBeans(ObjectName name, QueryExp query) { |
471 public Set<ObjectInstance> queryMBeans(ObjectName name, QueryExp query) { |
490 SecurityManager sm = System.getSecurityManager(); |
472 SecurityManager sm = System.getSecurityManager(); |
491 if (sm != null) { |
473 if (sm != null) { |
492 // Check if the caller has the right to invoke 'queryMBeans' |
474 // Check if the caller has the right to invoke 'queryMBeans' |
493 // |
475 // |
494 checkMBeanPermission(mbeanServerName,(String) null, null, null, "queryMBeans"); |
476 checkMBeanPermission((String) null, null, null, "queryMBeans"); |
495 |
477 |
496 // Perform query without "query". |
478 // Perform query without "query". |
497 // |
479 // |
498 Set<ObjectInstance> list = queryMBeansImpl(name, null); |
480 Set<ObjectInstance> list = queryMBeansImpl(name, null); |
499 |
481 |
502 // |
484 // |
503 Set<ObjectInstance> allowedList = |
485 Set<ObjectInstance> allowedList = |
504 new HashSet<ObjectInstance>(list.size()); |
486 new HashSet<ObjectInstance>(list.size()); |
505 for (ObjectInstance oi : list) { |
487 for (ObjectInstance oi : list) { |
506 try { |
488 try { |
507 checkMBeanPermission(mbeanServerName,oi.getClassName(), null, |
489 checkMBeanPermission(oi.getClassName(), null, |
508 oi.getObjectName(), "queryMBeans"); |
490 oi.getObjectName(), "queryMBeans"); |
509 allowedList.add(oi); |
491 allowedList.add(oi); |
510 } catch (SecurityException e) { |
492 } catch (SecurityException e) { |
511 // OK: Do not add this ObjectInstance to the list |
493 // OK: Do not add this ObjectInstance to the list |
512 } |
494 } |
535 Set<ObjectName> queryList; |
517 Set<ObjectName> queryList; |
536 SecurityManager sm = System.getSecurityManager(); |
518 SecurityManager sm = System.getSecurityManager(); |
537 if (sm != null) { |
519 if (sm != null) { |
538 // Check if the caller has the right to invoke 'queryNames' |
520 // Check if the caller has the right to invoke 'queryNames' |
539 // |
521 // |
540 checkMBeanPermission(mbeanServerName,(String) null, null, null, "queryNames"); |
522 checkMBeanPermission((String) null, null, null, "queryNames"); |
541 |
523 |
542 // Perform query without "query". |
524 // Perform query without "query". |
543 // |
525 // |
544 Set<ObjectInstance> list = queryMBeansImpl(name, null); |
526 Set<ObjectInstance> list = queryMBeansImpl(name, null); |
545 |
527 |
548 // |
530 // |
549 Set<ObjectInstance> allowedList = |
531 Set<ObjectInstance> allowedList = |
550 new HashSet<ObjectInstance>(list.size()); |
532 new HashSet<ObjectInstance>(list.size()); |
551 for (ObjectInstance oi : list) { |
533 for (ObjectInstance oi : list) { |
552 try { |
534 try { |
553 checkMBeanPermission(mbeanServerName, oi.getClassName(), null, |
535 checkMBeanPermission(oi.getClassName(), null, |
554 oi.getObjectName(), "queryNames"); |
536 oi.getObjectName(), "queryNames"); |
555 allowedList.add(oi); |
537 allowedList.add(oi); |
556 } catch (SecurityException e) { |
538 } catch (SecurityException e) { |
557 // OK: Do not add this ObjectInstance to the list |
539 // OK: Do not add this ObjectInstance to the list |
558 } |
540 } |
600 public String[] getDomains() { |
582 public String[] getDomains() { |
601 SecurityManager sm = System.getSecurityManager(); |
583 SecurityManager sm = System.getSecurityManager(); |
602 if (sm != null) { |
584 if (sm != null) { |
603 // Check if the caller has the right to invoke 'getDomains' |
585 // Check if the caller has the right to invoke 'getDomains' |
604 // |
586 // |
605 checkMBeanPermission(mbeanServerName, (String) null, null, null, "getDomains"); |
587 checkMBeanPermission((String) null, null, null, "getDomains"); |
606 |
588 |
607 // Return domains |
589 // Return domains |
608 // |
590 // |
609 String[] domains = repository.getDomains(); |
591 String[] domains = repository.getDomains(); |
610 |
592 |
612 // on each specific domain in the list. |
594 // on each specific domain in the list. |
613 // |
595 // |
614 List<String> result = new ArrayList<String>(domains.length); |
596 List<String> result = new ArrayList<String>(domains.length); |
615 for (int i = 0; i < domains.length; i++) { |
597 for (int i = 0; i < domains.length; i++) { |
616 try { |
598 try { |
617 ObjectName dom = ObjectName.valueOf(domains[i] + ":x=x"); |
599 ObjectName dom = Util.newObjectName(domains[i] + ":x=x"); |
618 checkMBeanPermission(mbeanServerName, (String) null, null, dom, "getDomains"); |
600 checkMBeanPermission((String) null, null, dom, "getDomains"); |
619 result.add(domains[i]); |
601 result.add(domains[i]); |
620 } catch (SecurityException e) { |
602 } catch (SecurityException e) { |
621 // OK: Do not add this domain to the list |
603 // OK: Do not add this domain to the list |
622 } |
604 } |
623 } |
605 } |
657 "getAttribute", |
639 "getAttribute", |
658 "Attribute = " + attribute + ", ObjectName = " + name); |
640 "Attribute = " + attribute + ", ObjectName = " + name); |
659 } |
641 } |
660 |
642 |
661 final DynamicMBean instance = getMBean(name); |
643 final DynamicMBean instance = getMBean(name); |
662 checkMBeanPermission(mbeanServerName, instance, attribute, |
644 checkMBeanPermission(instance, attribute, name, "getAttribute"); |
663 name, "getAttribute"); |
|
664 |
645 |
665 try { |
646 try { |
666 return instance.getAttribute(attribute); |
647 return instance.getAttribute(attribute); |
667 } catch (AttributeNotFoundException e) { |
648 } catch (AttributeNotFoundException e) { |
668 throw e; |
649 throw e; |
703 else { |
684 else { |
704 final String classname = getClassName(instance); |
685 final String classname = getClassName(instance); |
705 |
686 |
706 // Check if the caller has the right to invoke 'getAttribute' |
687 // Check if the caller has the right to invoke 'getAttribute' |
707 // |
688 // |
708 checkMBeanPermission(mbeanServerName, classname, null, name, "getAttribute"); |
689 checkMBeanPermission(classname, null, name, "getAttribute"); |
709 |
690 |
710 // Check if the caller has the right to invoke 'getAttribute' |
691 // Check if the caller has the right to invoke 'getAttribute' |
711 // on each specific attribute |
692 // on each specific attribute |
712 // |
693 // |
713 List<String> allowedList = |
694 List<String> allowedList = |
714 new ArrayList<String>(attributes.length); |
695 new ArrayList<String>(attributes.length); |
715 for (String attr : attributes) { |
696 for (String attr : attributes) { |
716 try { |
697 try { |
717 checkMBeanPermission(mbeanServerName, classname, attr, |
698 checkMBeanPermission(classname, attr, name, "getAttribute"); |
718 name, "getAttribute"); |
|
719 allowedList.add(attr); |
699 allowedList.add(attr); |
720 } catch (SecurityException e) { |
700 } catch (SecurityException e) { |
721 // OK: Do not add this attribute to the list |
701 // OK: Do not add this attribute to the list |
722 } |
702 } |
723 } |
703 } |
758 "setAttribute", "ObjectName = " + name + |
738 "setAttribute", "ObjectName = " + name + |
759 ", Attribute = " + attribute.getName()); |
739 ", Attribute = " + attribute.getName()); |
760 } |
740 } |
761 |
741 |
762 DynamicMBean instance = getMBean(name); |
742 DynamicMBean instance = getMBean(name); |
763 checkMBeanPermission(mbeanServerName, instance, attribute.getName(), |
743 checkMBeanPermission(instance, attribute.getName(), name, "setAttribute"); |
764 name, "setAttribute"); |
|
765 |
744 |
766 try { |
745 try { |
767 instance.setAttribute(attribute); |
746 instance.setAttribute(attribute); |
768 } catch (AttributeNotFoundException e) { |
747 } catch (AttributeNotFoundException e) { |
769 throw e; |
748 throw e; |
801 else { |
780 else { |
802 String classname = getClassName(instance); |
781 String classname = getClassName(instance); |
803 |
782 |
804 // Check if the caller has the right to invoke 'setAttribute' |
783 // Check if the caller has the right to invoke 'setAttribute' |
805 // |
784 // |
806 checkMBeanPermission(mbeanServerName, classname, null, name, "setAttribute"); |
785 checkMBeanPermission(classname, null, name, "setAttribute"); |
807 |
786 |
808 // Check if the caller has the right to invoke 'setAttribute' |
787 // Check if the caller has the right to invoke 'setAttribute' |
809 // on each specific attribute |
788 // on each specific attribute |
810 // |
789 // |
811 allowedAttributes = new AttributeList(attributes.size()); |
790 allowedAttributes = new AttributeList(attributes.size()); |
812 for (Attribute attribute : attributes.asList()) { |
791 for (Attribute attribute : attributes.asList()) { |
813 try { |
792 try { |
814 checkMBeanPermission(mbeanServerName, classname, attribute.getName(), |
793 checkMBeanPermission(classname, attribute.getName(), |
815 name, "setAttribute"); |
794 name, "setAttribute"); |
816 allowedAttributes.add(attribute); |
795 allowedAttributes.add(attribute); |
817 } catch (SecurityException e) { |
796 } catch (SecurityException e) { |
818 // OK: Do not add this attribute to the list |
797 // OK: Do not add this attribute to the list |
819 } |
798 } |
833 ReflectionException { |
812 ReflectionException { |
834 |
813 |
835 name = nonDefaultDomain(name); |
814 name = nonDefaultDomain(name); |
836 |
815 |
837 DynamicMBean instance = getMBean(name); |
816 DynamicMBean instance = getMBean(name); |
838 checkMBeanPermission(mbeanServerName, instance, operationName, |
817 checkMBeanPermission(instance, operationName, name, "invoke"); |
839 name, "invoke"); |
|
840 try { |
818 try { |
841 return instance.invoke(operationName, params, signature); |
819 return instance.invoke(operationName, params, signature); |
842 } catch (Throwable t) { |
820 } catch (Throwable t) { |
843 rethrowMaybeMBeanException(t); |
821 rethrowMaybeMBeanException(t); |
844 throw new AssertionError(); |
822 throw new AssertionError(); |
917 "Exception occurred trying to register the MBean"); |
895 "Exception occurred trying to register the MBean"); |
918 } |
896 } |
919 |
897 |
920 DynamicMBean mbean = Introspector.makeDynamicMBean(object); |
898 DynamicMBean mbean = Introspector.makeDynamicMBean(object); |
921 |
899 |
922 //Access the ObjectName template value only if the provided name is null |
|
923 if(name == null) { |
|
924 name = Introspector.templateToObjectName(mbean.getMBeanInfo(). |
|
925 getDescriptor(), mbean); |
|
926 } |
|
927 |
|
928 return registerDynamicMBean(classname, mbean, name); |
900 return registerDynamicMBean(classname, mbean, name); |
929 } |
901 } |
930 |
902 |
931 private ObjectInstance registerDynamicMBean(String classname, |
903 private ObjectInstance registerDynamicMBean(String classname, |
932 DynamicMBean mbean, |
904 DynamicMBean mbean, |
951 boolean registered = false; |
923 boolean registered = false; |
952 boolean registerFailed = false; |
924 boolean registerFailed = false; |
953 ResourceContext context = null; |
925 ResourceContext context = null; |
954 |
926 |
955 try { |
927 try { |
956 mbean = injectResources(mbean, server, logicalName); |
|
957 |
|
958 if (mbean instanceof DynamicMBean2) { |
928 if (mbean instanceof DynamicMBean2) { |
959 try { |
929 try { |
960 ((DynamicMBean2) mbean).preRegister2(server, logicalName); |
930 ((DynamicMBean2) mbean).preRegister2(server, logicalName); |
961 registerFailed = true; // until we succeed |
931 registerFailed = true; // until we succeed |
962 } catch (Exception e) { |
932 } catch (Exception e) { |
971 if (logicalName != name && logicalName != null) { |
941 if (logicalName != name && logicalName != null) { |
972 logicalName = |
942 logicalName = |
973 ObjectName.getInstance(nonDefaultDomain(logicalName)); |
943 ObjectName.getInstance(nonDefaultDomain(logicalName)); |
974 } |
944 } |
975 |
945 |
976 checkMBeanPermission(mbeanServerName, classname, null, logicalName, |
946 checkMBeanPermission(classname, null, logicalName, "registerMBean"); |
977 "registerMBean"); |
|
978 |
947 |
979 if (logicalName == null) { |
948 if (logicalName == null) { |
980 final RuntimeException wrapped = |
949 final RuntimeException wrapped = |
981 new IllegalArgumentException("No object name specified"); |
950 new IllegalArgumentException("No object name specified"); |
982 throw new RuntimeOperationsException(wrapped, |
951 throw new RuntimeOperationsException(wrapped, |
986 final Object resource = getResource(mbean); |
955 final Object resource = getResource(mbean); |
987 |
956 |
988 // Register the MBean with the repository. |
957 // Register the MBean with the repository. |
989 // Returns the resource context that was used. |
958 // Returns the resource context that was used. |
990 // The returned context does nothing for regular MBeans. |
959 // The returned context does nothing for regular MBeans. |
991 // For ClassLoader MBeans and JMXNamespace (and JMXDomain) |
960 // For ClassLoader MBeans the context makes it possible to register these |
992 // MBeans - the context makes it possible to register these |
|
993 // objects with the appropriate framework artifacts, such as |
961 // objects with the appropriate framework artifacts, such as |
994 // the CLR or the dispatcher, from within the repository lock. |
962 // the CLR, from within the repository lock. |
995 // In case of success, we also need to call context.done() at the |
963 // In case of success, we also need to call context.done() at the |
996 // end of this method. |
964 // end of this method. |
997 // |
965 // |
998 context = registerWithRepository(resource, mbean, logicalName); |
966 context = registerWithRepository(resource, mbean, logicalName); |
999 |
967 |
1041 throwMBeanRegistrationException(t, "in preRegister method"); |
1009 throwMBeanRegistrationException(t, "in preRegister method"); |
1042 } |
1010 } |
1043 |
1011 |
1044 if (newName != null) return newName; |
1012 if (newName != null) return newName; |
1045 else return name; |
1013 else return name; |
1046 } |
|
1047 |
|
1048 private static DynamicMBean injectResources( |
|
1049 DynamicMBean mbean, MBeanServer mbs, ObjectName name) |
|
1050 throws MBeanRegistrationException { |
|
1051 try { |
|
1052 Object resource = getResource(mbean); |
|
1053 MBeanInjector.inject(resource, mbs, name); |
|
1054 if (MBeanInjector.injectsSendNotification(resource)) { |
|
1055 MBeanNotificationInfo[] mbnis = |
|
1056 mbean.getMBeanInfo().getNotifications(); |
|
1057 NotificationBroadcasterSupport nbs = |
|
1058 new NotificationBroadcasterSupport(mbnis); |
|
1059 MBeanInjector.injectSendNotification(resource, nbs); |
|
1060 mbean = NotifySupport.wrap(mbean, nbs); |
|
1061 } |
|
1062 return mbean; |
|
1063 } catch (Throwable t) { |
|
1064 throwMBeanRegistrationException(t, "injecting @Resources"); |
|
1065 return null; // not reached |
|
1066 } |
|
1067 } |
1014 } |
1068 |
1015 |
1069 private static void postRegister( |
1016 private static void postRegister( |
1070 ObjectName logicalName, DynamicMBean mbean, |
1017 ObjectName logicalName, DynamicMBean mbean, |
1071 boolean registrationDone, boolean registerFailed) { |
1018 boolean registrationDone, boolean registerFailed) { |
1149 } |
1096 } |
1150 return obj; |
1097 return obj; |
1151 } |
1098 } |
1152 |
1099 |
1153 private static Object getResource(DynamicMBean mbean) { |
1100 private static Object getResource(DynamicMBean mbean) { |
1154 if (mbean instanceof DynamicWrapperMBean) |
1101 if (mbean instanceof DynamicMBean2) |
1155 return ((DynamicWrapperMBean) mbean).getWrappedObject(); |
1102 return ((DynamicMBean2) mbean).getResource(); |
1156 else |
1103 else |
1157 return mbean; |
1104 return mbean; |
1158 } |
|
1159 |
|
1160 private static ClassLoader getResourceLoader(DynamicMBean mbean) { |
|
1161 if (mbean instanceof DynamicWrapperMBean) |
|
1162 return ((DynamicWrapperMBean) mbean).getWrappedClassLoader(); |
|
1163 else |
|
1164 return mbean.getClass().getClassLoader(); |
|
1165 } |
1105 } |
1166 |
1106 |
1167 private ObjectName nonDefaultDomain(ObjectName name) { |
1107 private ObjectName nonDefaultDomain(ObjectName name) { |
1168 if (name == null || name.getDomain().length() > 0) |
1108 if (name == null || name.getDomain().length() > 0) |
1169 return name; |
1109 return name; |
1175 fact that toString() works like that and that it |
1115 fact that toString() works like that and that it |
1176 leaves wildcards in place (so we can detect an error |
1116 leaves wildcards in place (so we can detect an error |
1177 if one is supplied where it shouldn't be). */ |
1117 if one is supplied where it shouldn't be). */ |
1178 final String completeName = domain + name; |
1118 final String completeName = domain + name; |
1179 |
1119 |
1180 return ObjectName.valueOf(completeName); |
1120 return Util.newObjectName(completeName); |
1181 } |
1121 } |
1182 |
1122 |
1183 public String getDefaultDomain() { |
1123 public String getDefaultDomain() { |
1184 return domain; |
1124 return domain; |
1185 } |
1125 } |
1241 DefaultMBeanServerInterceptor.class.getName(), |
1181 DefaultMBeanServerInterceptor.class.getName(), |
1242 "addNotificationListener", "ObjectName = " + name); |
1182 "addNotificationListener", "ObjectName = " + name); |
1243 } |
1183 } |
1244 |
1184 |
1245 DynamicMBean instance = getMBean(name); |
1185 DynamicMBean instance = getMBean(name); |
1246 checkMBeanPermission(mbeanServerName, instance, null, |
1186 checkMBeanPermission(instance, null, name, "addNotificationListener"); |
1247 name, "addNotificationListener"); |
|
1248 |
1187 |
1249 NotificationBroadcaster broadcaster = |
1188 NotificationBroadcaster broadcaster = |
1250 getNotificationBroadcaster(name, instance, |
1189 getNotificationBroadcaster(name, instance, |
1251 NotificationBroadcaster.class); |
1190 NotificationBroadcaster.class); |
1252 |
1191 |
1379 DefaultMBeanServerInterceptor.class.getName(), |
1318 DefaultMBeanServerInterceptor.class.getName(), |
1380 "removeNotificationListener", "ObjectName = " + name); |
1319 "removeNotificationListener", "ObjectName = " + name); |
1381 } |
1320 } |
1382 |
1321 |
1383 DynamicMBean instance = getMBean(name); |
1322 DynamicMBean instance = getMBean(name); |
1384 checkMBeanPermission(mbeanServerName, instance, null, name, |
1323 checkMBeanPermission(instance, null, name, "removeNotificationListener"); |
1385 "removeNotificationListener"); |
|
1386 |
1324 |
1387 /* We could simplify the code by assigning broadcaster after |
1325 /* We could simplify the code by assigning broadcaster after |
1388 assigning listenerWrapper, but that would change the error |
1326 assigning listenerWrapper, but that would change the error |
1389 behavior when both the broadcaster and the listener are |
1327 behavior when both the broadcaster and the listener are |
1390 erroneous. */ |
1328 erroneous. */ |
1413 private static <T extends NotificationBroadcaster> |
1351 private static <T extends NotificationBroadcaster> |
1414 T getNotificationBroadcaster(ObjectName name, Object instance, |
1352 T getNotificationBroadcaster(ObjectName name, Object instance, |
1415 Class<T> reqClass) { |
1353 Class<T> reqClass) { |
1416 if (reqClass.isInstance(instance)) |
1354 if (reqClass.isInstance(instance)) |
1417 return reqClass.cast(instance); |
1355 return reqClass.cast(instance); |
1418 if (instance instanceof DynamicWrapperMBean) |
1356 if (instance instanceof DynamicMBean2) |
1419 instance = ((DynamicWrapperMBean) instance).getWrappedObject(); |
1357 instance = ((DynamicMBean2) instance).getResource(); |
1420 if (reqClass.isInstance(instance)) |
1358 if (reqClass.isInstance(instance)) |
1421 return reqClass.cast(instance); |
1359 return reqClass.cast(instance); |
1422 final RuntimeException exc = |
1360 final RuntimeException exc = |
1423 new IllegalArgumentException(name.getCanonicalName()); |
1361 new IllegalArgumentException(name.getCanonicalName()); |
1424 final String msg = |
1362 final String msg = |
1450 } |
1388 } |
1451 if (mbi == null) |
1389 if (mbi == null) |
1452 throw new JMRuntimeException("MBean " + name + |
1390 throw new JMRuntimeException("MBean " + name + |
1453 "has no MBeanInfo"); |
1391 "has no MBeanInfo"); |
1454 |
1392 |
1455 checkMBeanPermission(mbeanServerName, mbi.getClassName(), null, name, "getMBeanInfo"); |
1393 checkMBeanPermission(mbi.getClassName(), null, name, "getMBeanInfo"); |
1456 |
1394 |
1457 return mbi; |
1395 return mbi; |
1458 } |
1396 } |
1459 |
1397 |
1460 public boolean isInstanceOf(ObjectName name, String className) |
1398 public boolean isInstanceOf(ObjectName name, String className) |
1461 throws InstanceNotFoundException { |
1399 throws InstanceNotFoundException { |
1462 |
1400 |
1463 final DynamicMBean instance = getMBean(name); |
1401 final DynamicMBean instance = getMBean(name); |
1464 checkMBeanPermission(mbeanServerName, |
1402 checkMBeanPermission(instance, null, name, "isInstanceOf"); |
1465 instance, null, name, "isInstanceOf"); |
|
1466 |
1403 |
1467 try { |
1404 try { |
1468 Object resource = getResource(instance); |
1405 Object resource = getResource(instance); |
1469 |
1406 |
1470 final String resourceClassName = |
1407 final String resourceClassName = |
1472 getClassName((DynamicMBean) resource) : |
1409 getClassName((DynamicMBean) resource) : |
1473 resource.getClass().getName(); |
1410 resource.getClass().getName(); |
1474 |
1411 |
1475 if (resourceClassName.equals(className)) |
1412 if (resourceClassName.equals(className)) |
1476 return true; |
1413 return true; |
1477 final ClassLoader cl = getResourceLoader(instance); |
1414 final ClassLoader cl = resource.getClass().getClassLoader(); |
1478 |
1415 |
1479 final Class<?> classNameClass = Class.forName(className, false, cl); |
1416 final Class<?> classNameClass = Class.forName(className, false, cl); |
1480 if (classNameClass.isInstance(resource)) |
1417 if (classNameClass.isInstance(resource)) |
1481 return true; |
|
1482 |
|
1483 // Ensure that isInstanceOf(NotificationEmitter) is true when |
|
1484 // the MBean is a NotificationEmitter by virtue of a @Resource |
|
1485 // annotation specifying a SendNotification resource. |
|
1486 // This is a hack. |
|
1487 if (instance instanceof NotificationBroadcaster && |
|
1488 classNameClass.isAssignableFrom(NotificationEmitter.class)) |
|
1489 return true; |
1418 return true; |
1490 |
1419 |
1491 final Class<?> resourceClass = Class.forName(resourceClassName, false, cl); |
1420 final Class<?> resourceClass = Class.forName(resourceClassName, false, cl); |
1492 return classNameClass.isAssignableFrom(resourceClass); |
1421 return classNameClass.isAssignableFrom(resourceClass); |
1493 } catch (Exception x) { |
1422 } catch (Exception x) { |
1511 */ |
1440 */ |
1512 public ClassLoader getClassLoaderFor(ObjectName mbeanName) |
1441 public ClassLoader getClassLoaderFor(ObjectName mbeanName) |
1513 throws InstanceNotFoundException { |
1442 throws InstanceNotFoundException { |
1514 |
1443 |
1515 DynamicMBean instance = getMBean(mbeanName); |
1444 DynamicMBean instance = getMBean(mbeanName); |
1516 checkMBeanPermission(mbeanServerName, instance, null, mbeanName, |
1445 checkMBeanPermission(instance, null, mbeanName, "getClassLoaderFor"); |
1517 "getClassLoaderFor"); |
1446 return getResource(instance).getClass().getClassLoader(); |
1518 return getResourceLoader(instance); |
|
1519 } |
1447 } |
1520 |
1448 |
1521 /** |
1449 /** |
1522 * <p>Return the named {@link java.lang.ClassLoader}. |
1450 * <p>Return the named {@link java.lang.ClassLoader}. |
1523 * @param loaderName The ObjectName of the ClassLoader. |
1451 * @param loaderName The ObjectName of the ClassLoader. |
1527 */ |
1455 */ |
1528 public ClassLoader getClassLoader(ObjectName loaderName) |
1456 public ClassLoader getClassLoader(ObjectName loaderName) |
1529 throws InstanceNotFoundException { |
1457 throws InstanceNotFoundException { |
1530 |
1458 |
1531 if (loaderName == null) { |
1459 if (loaderName == null) { |
1532 checkMBeanPermission(mbeanServerName, (String) null, null, null, "getClassLoader"); |
1460 checkMBeanPermission((String) null, null, null, "getClassLoader"); |
1533 return server.getClass().getClassLoader(); |
1461 return server.getClass().getClassLoader(); |
1534 } |
1462 } |
1535 |
1463 |
1536 DynamicMBean instance = getMBean(loaderName); |
1464 DynamicMBean instance = getMBean(loaderName); |
1537 checkMBeanPermission(mbeanServerName, instance, null, loaderName, |
1465 checkMBeanPermission(instance, null, loaderName, "getClassLoader"); |
1538 "getClassLoader"); |
|
1539 |
1466 |
1540 Object resource = getResource(instance); |
1467 Object resource = getResource(instance); |
1541 |
1468 |
1542 /* Check if the given MBean is a ClassLoader */ |
1469 /* Check if the given MBean is a ClassLoader */ |
1543 if (!(resource instanceof ClassLoader)) |
1470 if (!(resource instanceof ClassLoader)) |
1755 } else |
1682 } else |
1756 return null; |
1683 return null; |
1757 } |
1684 } |
1758 } |
1685 } |
1759 |
1686 |
1687 public Object instantiate(String className) throws ReflectionException, |
|
1688 MBeanException { |
|
1689 throw new UnsupportedOperationException("Not supported yet."); |
|
1690 } |
|
1691 |
|
1692 public Object instantiate(String className, ObjectName loaderName) throws ReflectionException, |
|
1693 MBeanException, |
|
1694 InstanceNotFoundException { |
|
1695 throw new UnsupportedOperationException("Not supported yet."); |
|
1696 } |
|
1697 |
|
1698 public Object instantiate(String className, Object[] params, |
|
1699 String[] signature) throws ReflectionException, MBeanException { |
|
1700 throw new UnsupportedOperationException("Not supported yet."); |
|
1701 } |
|
1702 |
|
1703 public Object instantiate(String className, ObjectName loaderName, |
|
1704 Object[] params, String[] signature) throws ReflectionException, |
|
1705 MBeanException, |
|
1706 InstanceNotFoundException { |
|
1707 throw new UnsupportedOperationException("Not supported yet."); |
|
1708 } |
|
1709 |
|
1710 public ObjectInputStream deserialize(ObjectName name, byte[] data) throws InstanceNotFoundException, |
|
1711 OperationsException { |
|
1712 throw new UnsupportedOperationException("Not supported yet."); |
|
1713 } |
|
1714 |
|
1715 public ObjectInputStream deserialize(String className, byte[] data) throws OperationsException, |
|
1716 ReflectionException { |
|
1717 throw new UnsupportedOperationException("Not supported yet."); |
|
1718 } |
|
1719 |
|
1720 public ObjectInputStream deserialize(String className, ObjectName loaderName, |
|
1721 byte[] data) throws InstanceNotFoundException, OperationsException, |
|
1722 ReflectionException { |
|
1723 throw new UnsupportedOperationException("Not supported yet."); |
|
1724 } |
|
1725 |
|
1726 public ClassLoaderRepository getClassLoaderRepository() { |
|
1727 throw new UnsupportedOperationException("Not supported yet."); |
|
1728 } |
|
1729 |
|
1760 private static class ListenerWrapper implements NotificationListener { |
1730 private static class ListenerWrapper implements NotificationListener { |
1761 ListenerWrapper(NotificationListener l, ObjectName name, |
1731 ListenerWrapper(NotificationListener l, ObjectName name, |
1762 Object mbean) { |
1732 Object mbean) { |
1763 this.listener = l; |
1733 this.listener = l; |
1764 this.name = name; |
1734 this.name = name; |
1832 return ((DynamicMBean2) mbean).getClassName(); |
1802 return ((DynamicMBean2) mbean).getClassName(); |
1833 else |
1803 else |
1834 return mbean.getMBeanInfo().getClassName(); |
1804 return mbean.getMBeanInfo().getClassName(); |
1835 } |
1805 } |
1836 |
1806 |
1837 private static void checkMBeanPermission(String mbeanServerName, |
1807 private static void checkMBeanPermission(DynamicMBean mbean, |
1838 DynamicMBean mbean, |
|
1839 String member, |
1808 String member, |
1840 ObjectName objectName, |
1809 ObjectName objectName, |
1841 String actions) { |
1810 String actions) { |
1842 SecurityManager sm = System.getSecurityManager(); |
1811 SecurityManager sm = System.getSecurityManager(); |
1843 if (sm != null) { |
1812 if (sm != null) { |
1844 checkMBeanPermission(mbeanServerName, |
1813 checkMBeanPermission(safeGetClassName(mbean), |
1845 safeGetClassName(mbean), |
|
1846 member, |
1814 member, |
1847 objectName, |
1815 objectName, |
1848 actions); |
1816 actions); |
1849 } |
1817 } |
1850 } |
1818 } |
1851 |
1819 |
1852 private static void checkMBeanPermission(String mbeanServerName, |
1820 private static void checkMBeanPermission(String classname, |
1853 String classname, |
|
1854 String member, |
1821 String member, |
1855 ObjectName objectName, |
1822 ObjectName objectName, |
1856 String actions) { |
1823 String actions) { |
1857 SecurityManager sm = System.getSecurityManager(); |
1824 SecurityManager sm = System.getSecurityManager(); |
1858 if (sm != null) { |
1825 if (sm != null) { |
1859 Permission perm = new MBeanPermission(mbeanServerName, |
1826 Permission perm = new MBeanPermission(classname, |
1860 classname, |
|
1861 member, |
1827 member, |
1862 objectName, |
1828 objectName, |
1863 actions); |
1829 actions); |
1864 sm.checkPermission(perm); |
1830 sm.checkPermission(perm); |
1865 } |
1831 } |
1921 final DynamicMBean object, |
1887 final DynamicMBean object, |
1922 final ObjectName logicalName) |
1888 final ObjectName logicalName) |
1923 throws InstanceAlreadyExistsException, |
1889 throws InstanceAlreadyExistsException, |
1924 MBeanRegistrationException { |
1890 MBeanRegistrationException { |
1925 |
1891 |
1926 // this will throw an exception if the pair (resource, logicalName) |
|
1927 // violates namespace conventions - for instance, if logicalName |
|
1928 // ends with // but resource is not a JMXNamespace. |
|
1929 // |
|
1930 checkResourceObjectNameConstraints(resource, logicalName); |
|
1931 |
|
1932 // Creates a registration context, if needed. |
1892 // Creates a registration context, if needed. |
1933 // |
1893 // |
1934 final ResourceContext context = |
1894 final ResourceContext context = |
1935 makeResourceContextFor(resource, logicalName); |
1895 makeResourceContextFor(resource, logicalName); |
1936 |
1896 |
1992 sendNotification(MBeanServerNotification.UNREGISTRATION_NOTIFICATION, |
1952 sendNotification(MBeanServerNotification.UNREGISTRATION_NOTIFICATION, |
1993 logicalName); |
1953 logicalName); |
1994 return context; |
1954 return context; |
1995 } |
1955 } |
1996 |
1956 |
1997 |
|
1998 /** |
|
1999 * Checks that the ObjectName is legal with regards to the |
|
2000 * type of the MBean resource. |
|
2001 * If the MBean name is domain:type=JMXDomain, the |
|
2002 * MBean must be a JMXDomain. |
|
2003 * If the MBean name is namespace//:type=JMXNamespace, the |
|
2004 * MBean must be a JMXNamespace. |
|
2005 * If the MBean is a JMXDomain, its name |
|
2006 * must be domain:type=JMXDomain. |
|
2007 * If the MBean is a JMXNamespace, its name |
|
2008 * must be namespace//:type=JMXNamespace. |
|
2009 */ |
|
2010 private void checkResourceObjectNameConstraints(Object resource, |
|
2011 ObjectName logicalName) |
|
2012 throws MBeanRegistrationException { |
|
2013 try { |
|
2014 dispatcher.checkLocallyRegistrable(resource, logicalName); |
|
2015 } catch (Throwable x) { |
|
2016 DefaultMBeanServerInterceptor.throwMBeanRegistrationException(x, "validating ObjectName"); |
|
2017 } |
|
2018 } |
|
2019 |
|
2020 /** |
|
2021 * Registers a JMXNamespace with the dispatcher. |
|
2022 * This method is called by the ResourceContext from within the |
|
2023 * repository lock. |
|
2024 * @param namespace The JMXNamespace |
|
2025 * @param logicalName The JMXNamespaceMBean ObjectName |
|
2026 * @param postQueue A queue that will be processed after postRegister. |
|
2027 */ |
|
2028 private void addJMXNamespace(JMXNamespace namespace, |
|
2029 final ObjectName logicalName, |
|
2030 final Queue<Runnable> postQueue) { |
|
2031 dispatcher.addInterceptorFor(logicalName, namespace, postQueue); |
|
2032 } |
|
2033 |
|
2034 /** |
|
2035 * Unregisters a JMXNamespace from the dispatcher. |
|
2036 * This method is called by the ResourceContext from within the |
|
2037 * repository lock. |
|
2038 * @param namespace The JMXNamespace |
|
2039 * @param logicalName The JMXNamespaceMBean ObjectName |
|
2040 * @param postQueue A queue that will be processed after postDeregister. |
|
2041 */ |
|
2042 private void removeJMXNamespace(JMXNamespace namespace, |
|
2043 final ObjectName logicalName, |
|
2044 final Queue<Runnable> postQueue) { |
|
2045 dispatcher.removeInterceptorFor(logicalName, namespace, postQueue); |
|
2046 } |
|
2047 |
1957 |
2048 /** |
1958 /** |
2049 * Registers a ClassLoader with the CLR. |
1959 * Registers a ClassLoader with the CLR. |
2050 * This method is called by the ResourceContext from within the |
1960 * This method is called by the ResourceContext from within the |
2051 * repository lock. |
1961 * repository lock. |
2098 } |
2008 } |
2099 } |
2009 } |
2100 |
2010 |
2101 |
2011 |
2102 /** |
2012 /** |
2103 * Creates a ResourceContext for a JMXNamespace MBean. |
|
2104 * The resource context makes it possible to add the JMXNamespace to |
|
2105 * (ResourceContext.registering) or resp. remove the JMXNamespace from |
|
2106 * (ResourceContext.unregistered) the NamespaceDispatchInterceptor |
|
2107 * when the associated MBean is added to or resp. removed from the |
|
2108 * repository. |
|
2109 * Note: JMXDomains are special sub classes of JMXNamespaces and |
|
2110 * are also handled by this object. |
|
2111 * |
|
2112 * @param namespace The JMXNamespace MBean being registered or |
|
2113 * unregistered. |
|
2114 * @param logicalName The name of the JMXNamespace MBean. |
|
2115 * @return a ResourceContext that takes in charge the addition or removal |
|
2116 * of the namespace to or from the NamespaceDispatchInterceptor. |
|
2117 */ |
|
2118 private ResourceContext createJMXNamespaceContext( |
|
2119 final JMXNamespace namespace, |
|
2120 final ObjectName logicalName) { |
|
2121 final Queue<Runnable> doneTaskQueue = new LinkedList<Runnable>(); |
|
2122 return new ResourceContext() { |
|
2123 |
|
2124 public void registering() { |
|
2125 addJMXNamespace(namespace, logicalName, doneTaskQueue); |
|
2126 } |
|
2127 |
|
2128 public void unregistered() { |
|
2129 removeJMXNamespace(namespace, logicalName, |
|
2130 doneTaskQueue); |
|
2131 } |
|
2132 |
|
2133 public void done() { |
|
2134 for (Runnable r : doneTaskQueue) { |
|
2135 try { |
|
2136 r.run(); |
|
2137 } catch (RuntimeException x) { |
|
2138 MBEANSERVER_LOGGER.log(Level.FINE, |
|
2139 "Failed to process post queue for "+ |
|
2140 logicalName, x); |
|
2141 } |
|
2142 } |
|
2143 } |
|
2144 }; |
|
2145 } |
|
2146 |
|
2147 /** |
|
2148 * Creates a ResourceContext for a ClassLoader MBean. |
2013 * Creates a ResourceContext for a ClassLoader MBean. |
2149 * The resource context makes it possible to add the ClassLoader to |
2014 * The resource context makes it possible to add the ClassLoader to |
2150 * (ResourceContext.registering) or resp. remove the ClassLoader from |
2015 * (ResourceContext.registering) or resp. remove the ClassLoader from |
2151 * (ResourceContext.unregistered) the CLR |
2016 * (ResourceContext.unregistered) the CLR |
2152 * when the associated MBean is added to or resp. removed from the |
2017 * when the associated MBean is added to or resp. removed from the |
2178 |
2043 |
2179 /** |
2044 /** |
2180 * Creates a ResourceContext for the given resource. |
2045 * Creates a ResourceContext for the given resource. |
2181 * If the resource does not need a ResourceContext, returns |
2046 * If the resource does not need a ResourceContext, returns |
2182 * ResourceContext.NONE. |
2047 * ResourceContext.NONE. |
2183 * At this time, only JMXNamespaces and ClassLoaders need a |
2048 * At this time, only ClassLoaders need a ResourceContext. |
2184 * ResourceContext. |
|
2185 * |
2049 * |
2186 * @param resource The resource being registered or unregistered. |
2050 * @param resource The resource being registered or unregistered. |
2187 * @param logicalName The name of the associated MBean. |
2051 * @param logicalName The name of the associated MBean. |
2188 * @return |
2052 * @return |
2189 */ |
2053 */ |
2190 private ResourceContext makeResourceContextFor(Object resource, |
2054 private ResourceContext makeResourceContextFor(Object resource, |
2191 ObjectName logicalName) { |
2055 ObjectName logicalName) { |
2192 if (resource instanceof JMXNamespace) { |
|
2193 return createJMXNamespaceContext((JMXNamespace) resource, |
|
2194 logicalName); |
|
2195 } |
|
2196 if (resource instanceof ClassLoader) { |
2056 if (resource instanceof ClassLoader) { |
2197 return createClassLoaderContext((ClassLoader) resource, |
2057 return createClassLoaderContext((ClassLoader) resource, |
2198 logicalName); |
2058 logicalName); |
2199 } |
2059 } |
2200 return ResourceContext.NONE; |
2060 return ResourceContext.NONE; |