1 7 8 package com.sun.jmx.interceptor; 9 10 import java.util.ArrayList ; 12 import java.util.Iterator ; 13 import java.util.Set ; 14 import java.util.HashSet ; 15 import java.util.WeakHashMap ; 16 import java.lang.ref.WeakReference ; 17 import java.lang.reflect.InvocationTargetException ; 18 import java.lang.reflect.Method ; 19 import java.lang.reflect.Constructor ; 20 import java.io.OptionalDataException ; 21 import java.io.ObjectInputStream ; 22 import java.io.ObjectOutputStream ; 23 import java.io.ByteArrayInputStream ; 24 import java.io.ByteArrayOutputStream ; 25 import java.io.PrintWriter ; 26 import java.io.StringWriter ; 27 import java.io.IOException ; 28 import java.security.AccessControlContext ; 29 import java.security.Permission ; 30 import java.security.ProtectionDomain ; 31 import java.security.AccessController ; 32 import java.security.PrivilegedAction ; 33 34 import javax.management.*; 36 import javax.management.loading.ClassLoaderRepository ; 37 38 import com.sun.jmx.mbeanserver.ModifiableClassLoaderRepository; 40 import com.sun.jmx.mbeanserver.MetaData; 41 import com.sun.jmx.mbeanserver.MetaDataImpl; 42 import com.sun.jmx.mbeanserver.MBeanInstantiator; 43 import com.sun.jmx.mbeanserver.Repository; 44 import com.sun.jmx.mbeanserver.RepositorySupport; 45 import com.sun.jmx.mbeanserver.NamedObject; 46 import com.sun.jmx.defaults.ServiceName; 47 import com.sun.jmx.trace.Trace; 48 49 71 public class DefaultMBeanServerInterceptor implements MBeanServerInterceptor { 72 73 74 private final static ObjectName _MBSDelegateObjectName; 75 static { 76 try { 77 _MBSDelegateObjectName = new ObjectName(ServiceName.DELEGATE); 78 } catch (MalformedObjectNameException e) { 79 throw new UnsupportedOperationException (e.getMessage()); 80 } 81 } 82 83 85 private final transient MBeanInstantiator instantiator; 86 87 89 private transient MBeanServer server = null; 90 91 93 private final transient MBeanServerDelegate delegate; 94 95 96 private final transient MetaData meta; 97 98 99 private final transient Repository repository; 100 101 102 103 private final transient WeakHashMap listenerWrappers = new WeakHashMap (); 104 105 106 private final String domain; 107 108 109 private boolean queryByRepo; 110 111 112 115 116 private final static String dbgTag = "DefaultMBeanServerInterceptor"; 117 118 135 public DefaultMBeanServerInterceptor(String domain, 136 MBeanServer outer, 137 MBeanServerDelegate delegate, 138 MBeanInstantiator instantiator) { 139 this(outer, delegate, instantiator, null, 140 new RepositorySupport((domain==null?ServiceName.DOMAIN:domain))); 141 } 142 143 161 public DefaultMBeanServerInterceptor(MBeanServer outer, 162 MBeanServerDelegate delegate, 163 MBeanInstantiator instantiator, 164 MetaData metadata, 165 Repository repository) { 166 if (outer == null) throw new 167 IllegalArgumentException ("outer MBeanServer cannot be null"); 168 if (delegate == null) throw new 169 IllegalArgumentException ("MBeanServerDelegate cannot be null"); 170 if (instantiator == null) throw new 171 IllegalArgumentException ("MBeanInstantiator cannot be null"); 172 if (metadata == null) 173 metadata = new MetaDataImpl(instantiator); 174 if (repository == null) 175 repository = new RepositorySupport(ServiceName.DOMAIN); 176 177 this.server = outer; 178 this.delegate = delegate; 179 this.instantiator = instantiator; 180 this.meta = metadata; 181 this.repository = repository; 182 this.domain = repository.getDefaultDomain(); 183 } 184 185 public ObjectInstance createMBean(String className, ObjectName name) 186 throws ReflectionException, InstanceAlreadyExistsException, 187 MBeanRegistrationException, MBeanException, 188 NotCompliantMBeanException { 189 190 return createMBean(className, name, (Object []) null, (String []) null); 191 192 } 193 194 public ObjectInstance createMBean(String className, ObjectName name, 195 ObjectName loaderName) 196 throws ReflectionException, InstanceAlreadyExistsException, 197 MBeanRegistrationException, MBeanException, 198 NotCompliantMBeanException, InstanceNotFoundException { 199 200 return createMBean(className, name, loaderName, (Object []) null, 201 (String []) null); 202 } 203 204 public ObjectInstance createMBean(String className, ObjectName name, 205 Object [] params, String [] signature) 206 throws ReflectionException, InstanceAlreadyExistsException, 207 MBeanRegistrationException, MBeanException, 208 NotCompliantMBeanException { 209 210 try { 211 return createMBean(className, name, null, true, 212 params, signature); 213 } catch (InstanceNotFoundException e) { 214 216 throw new IllegalArgumentException ("Unexpected exception: " + e); 217 } 218 } 219 220 public ObjectInstance createMBean(String className, ObjectName name, 221 ObjectName loaderName, 222 Object [] params, String [] signature) 223 throws ReflectionException, InstanceAlreadyExistsException, 224 MBeanRegistrationException, MBeanException, 225 NotCompliantMBeanException, InstanceNotFoundException { 226 227 return createMBean(className, name, loaderName, false, 228 params, signature); 229 } 230 231 private ObjectInstance createMBean(String className, ObjectName name, 232 ObjectName loaderName, 233 boolean withDefaultLoaderRepository, 234 Object [] params, String [] signature) 235 throws ReflectionException, InstanceAlreadyExistsException, 236 MBeanRegistrationException, MBeanException, 237 NotCompliantMBeanException, InstanceNotFoundException { 238 239 ObjectName logicalName = name; 240 Class theClass; 241 242 if (className == null) { 243 final RuntimeException wrapped = 244 new IllegalArgumentException ("The class name cannot be null"); 245 throw new RuntimeOperationsException(wrapped, 246 "Exception occured during MBean creation"); 247 } 248 249 if (name != null) { 250 if (name.isPattern()) { 251 final RuntimeException wrapped = 252 new IllegalArgumentException ("Invalid name->" + 253 name.toString()); 254 final String msg = "Exception occurred during MBean creation"; 255 throw new RuntimeOperationsException(wrapped, msg); 256 } 257 258 name = nonDefaultDomain(name); 259 } 260 261 262 checkMBeanPermission(className, null, null, "instantiate"); 263 checkMBeanPermission(className, null, name, "registerMBean"); 264 265 266 if (withDefaultLoaderRepository) { 267 if (isTraceOn()) { 268 trace(dbgTag, "createMBean", "ClassName = " + className + 269 ",ObjectName = " + name); 270 } 271 theClass = 272 instantiator.findClassWithDefaultLoaderRepository(className); 273 } else if (loaderName == null) { 274 if (isTraceOn()) { 275 trace(dbgTag, "createMBean", "ClassName = " + className + 276 ",ObjectName = " + name + " Loader name = null"); 277 } 278 279 theClass = instantiator.findClass(className, 280 server.getClass().getClassLoader()); 281 } else { 282 loaderName = nonDefaultDomain(loaderName); 283 284 if (isTraceOn()) { 285 trace(dbgTag, "createMBean", "ClassName = " + className + 286 ",ObjectName = " + name + ",Loader name = "+ 287 loaderName.toString()); 288 } 289 290 theClass = instantiator.findClass(className, loaderName); 291 } 292 293 294 checkMBeanTrustPermission(theClass); 295 296 instantiator.testCreation(theClass); 298 299 meta.testCompliance(theClass); 301 302 Object moi= instantiator.instantiate(theClass, params, signature, 303 server.getClass().getClassLoader()); 304 305 final String infoClassName; 306 try { 307 infoClassName = meta.getMBeanClassName(moi); 308 } catch (IntrospectionException e) { 309 throw new NotCompliantMBeanException(e.getMessage()); 310 } 311 312 return registerCreatedObject(infoClassName, moi, name); 313 } 314 315 public ObjectInstance registerMBean(Object object, ObjectName name) 316 throws InstanceAlreadyExistsException, MBeanRegistrationException, 317 NotCompliantMBeanException { 318 319 Class theClass = object.getClass(); 322 323 meta.testCompliance(theClass); 325 326 327 final String infoClassName; 328 try { 329 infoClassName = meta.getMBeanClassName(object); 330 } catch (IntrospectionException e) { 331 throw new NotCompliantMBeanException(e.getMessage()); 332 } 333 334 checkMBeanPermission(infoClassName, null, name, "registerMBean"); 335 checkMBeanTrustPermission(theClass); 336 337 return registerObject(infoClassName, object, name); 338 } 339 340 public void unregisterMBean(ObjectName name) 341 throws InstanceNotFoundException, MBeanRegistrationException { 342 Object object; 343 344 if (name == null) { 345 final RuntimeException wrapped = 346 new IllegalArgumentException ("Object name cannot be null"); 347 throw new RuntimeOperationsException(wrapped, 348 "Exception occured trying to unregister the MBean"); 349 } 350 351 name = nonDefaultDomain(name); 352 353 354 Object instance = getMBean(name); 355 String classname = null; 356 try { 357 classname = meta.getMBeanClassName(instance); 358 } catch (IntrospectionException e) { 359 classname = null; 360 } catch (NotCompliantMBeanException e) { 361 classname = null; 362 } 363 checkMBeanPermission(classname, null, name, "unregisterMBean"); 364 365 368 synchronized(this) { 369 object = repository.retrieve(name); 370 if (object==null) { 371 if (isTraceOn()) { 372 trace("unregisterMBean", name+": Found no object"); 373 } 374 throw new InstanceNotFoundException(name.toString()); 375 } 376 if (object instanceof MBeanRegistration) { 377 meta.preDeregisterInvoker(object); 378 } 379 try { 381 repository.remove(name); 382 } 383 catch (InstanceNotFoundException e) { 384 throw e; 385 } 386 387 391 392 if (object instanceof ClassLoader 393 && object != server.getClass().getClassLoader()) { 394 final ModifiableClassLoaderRepository clr = 395 instantiator.getClassLoaderRepository(); 396 if (clr != null) clr.removeClassLoader(name); 397 } 398 } 399 400 if (isTraceOn()) { 404 trace("unregisterMBean", "Send delete notification of object " 405 + name.getCanonicalName()); 406 } 407 sendNotification(MBeanServerNotification.UNREGISTRATION_NOTIFICATION, 408 name); 409 410 if (object instanceof MBeanRegistration) { 411 meta.postDeregisterInvoker(object); 412 } 413 } 414 415 public ObjectInstance getObjectInstance(ObjectName name) 416 throws InstanceNotFoundException { 417 418 name = nonDefaultDomain(name); 419 Object obj = getMBean(name); 420 final String className; 421 try { 422 className = meta.getMBeanClassName(obj); 423 } catch (IntrospectionException x) { 424 debugX("getObjectInstance",x); 425 throw new JMRuntimeException("Can't obtain class name for " + 426 name + ": " + x); 427 } catch (NotCompliantMBeanException x) { 428 debugX("getObjectInstance",x); 429 throw new JMRuntimeException("Can't obtain class name for " + 430 name + ": " + x); 431 } 432 433 434 checkMBeanPermission(className, null, name, "getObjectInstance"); 435 436 return new ObjectInstance(name, className); 437 } 438 439 public Set queryMBeans(ObjectName name, QueryExp query) { 440 441 SecurityManager sm = System.getSecurityManager(); 442 if (sm != null) { 443 checkMBeanPermission(null, null, null, "queryMBeans"); 446 447 Set list = queryMBeansImpl(name, null); 450 451 Set allowedList = new HashSet (list.size()); 455 for (Iterator i = list.iterator(); i.hasNext(); ) { 456 try { 457 ObjectInstance oi = (ObjectInstance) i.next(); 458 checkMBeanPermission(oi.getClassName(), null, 459 oi.getObjectName(), "queryMBeans"); 460 allowedList.add(oi); 461 } catch (SecurityException e) { 462 } 464 } 465 466 return filterListOfObjectInstances(allowedList, query); 469 } else { 470 return queryMBeansImpl(name, query); 473 } 474 } 475 476 private Set queryMBeansImpl(ObjectName name, QueryExp query) { 477 Set list = null; 480 synchronized(this) { 481 list = repository.query(name, query); 482 } 483 if (queryByRepo) { 486 return list; 487 } else { 488 return (filterListOfObjects(list, query)); 491 } 492 } 493 494 public Set queryNames(ObjectName name, QueryExp query) { 495 496 SecurityManager sm = System.getSecurityManager(); 497 if (sm != null) { 498 checkMBeanPermission(null, null, null, "queryNames"); 501 502 Set list = queryMBeansImpl(name, null); 505 506 Set allowedList = new HashSet (list.size()); 510 for (Iterator i = list.iterator(); i.hasNext(); ) { 511 try { 512 ObjectInstance oi = (ObjectInstance) i.next(); 513 checkMBeanPermission(oi.getClassName(), null, 514 oi.getObjectName(), "queryNames"); 515 allowedList.add(oi); 516 } catch (SecurityException e) { 517 } 519 } 520 521 Set queryList = filterListOfObjectInstances(allowedList, query); 524 Set result = new HashSet (queryList.size()); 525 for (Iterator i = queryList.iterator(); i.hasNext(); ) { 526 ObjectInstance oi = (ObjectInstance) i.next(); 527 result.add(oi.getObjectName()); 528 } 529 return result; 530 } else { 531 Set queryList = queryMBeansImpl(name, query); 534 Set result = new HashSet (queryList.size()); 535 for (Iterator i = queryList.iterator(); i.hasNext(); ) { 536 ObjectInstance oi = (ObjectInstance) i.next(); 537 result.add(oi.getObjectName()); 538 } 539 return result; 540 } 541 } 542 543 public boolean isRegistered(ObjectName name) { 544 if (name == null) { 545 throw new RuntimeOperationsException( 546 new IllegalArgumentException ("Object name cannot be null"), 547 "Object name cannot be null"); 548 } 549 550 name = nonDefaultDomain(name); 551 552 555 synchronized(this) { 556 return (repository.contains(name)); 557 } 558 } 559 560 public String [] getDomains() { 561 562 SecurityManager sm = System.getSecurityManager(); 563 if (sm != null) { 564 checkMBeanPermission(null, null, null, "getDomains"); 567 568 String [] domains = repository.getDomains(); 571 572 ArrayList result = new ArrayList (domains.length); 576 for (int i = 0; i < domains.length; i++) { 577 try { 578 ObjectName domain = new ObjectName(domains[i] + ":x=x"); 579 checkMBeanPermission(null, null, domain, "getDomains"); 580 result.add(domains[i]); 581 } catch (MalformedObjectNameException e) { 582 error("getDomains", 584 "Failed to check permission for domain=" + 585 domains[i] + ". Error is: " + e); 586 debugX("getDomains",e); 587 } catch (SecurityException e) { 588 } 590 } 591 592 return (String []) result.toArray(new String [result.size()]); 595 } else { 596 return repository.getDomains(); 597 } 598 } 599 600 public Integer getMBeanCount() { 601 return (repository.getCount()); 602 } 603 604 public Object getAttribute(ObjectName name, String attribute) 605 throws MBeanException, AttributeNotFoundException, 606 InstanceNotFoundException, ReflectionException { 607 608 if (name == null) { 609 throw new RuntimeOperationsException(new 610 IllegalArgumentException ("Object name cannot be null"), 611 "Exception occured trying to invoke the getter on the MBean"); 612 } 613 if (attribute == null) { 614 throw new RuntimeOperationsException(new 615 IllegalArgumentException ("Attribute cannot be null"), 616 "Exception occured trying to invoke the getter on the MBean"); 617 } 618 619 name = nonDefaultDomain(name); 620 621 if (isTraceOn()) { 622 trace("getAttribute", "Attribute= " + attribute + 623 ", obj= " + name); 624 } 625 626 627 Object instance = getMBean(name); 628 String classname = null; 629 try { 630 classname = meta.getMBeanClassName(instance); 631 } catch (IntrospectionException e) { 632 classname = null; 633 } catch (NotCompliantMBeanException e) { 634 classname = null; 635 } 636 checkMBeanPermission(classname, attribute, name, "getAttribute"); 637 638 return meta.getAttribute(instance, attribute); 639 } 640 641 public AttributeList getAttributes(ObjectName name, String [] attributes) 642 throws InstanceNotFoundException, ReflectionException { 643 644 if (name == null) { 645 throw new RuntimeOperationsException(new 646 IllegalArgumentException ("ObjectName name cannot be null"), 647 "Exception occured trying to invoke the getter on the MBean"); 648 } 649 650 if (attributes == null) { 651 throw new RuntimeOperationsException(new 652 IllegalArgumentException ("Attributes cannot be null"), 653 "Exception occured trying to invoke the getter on the MBean"); 654 } 655 656 name = nonDefaultDomain(name); 657 658 if (isTraceOn()) { 659 trace("getAttributes", "Object= " + name); 660 } 661 662 Object instance = getMBean(name); 663 SecurityManager sm = System.getSecurityManager(); 664 if (sm != null) { 665 666 String classname = null; 667 try { 668 classname = meta.getMBeanClassName(instance); 669 } catch (IntrospectionException e) { 670 classname = null; 671 } catch (NotCompliantMBeanException e) { 672 classname = null; 673 } 674 675 checkMBeanPermission(classname, null, name, "getAttribute"); 678 679 ArrayList allowedList = new ArrayList (attributes.length); 683 for (int i = 0; i < attributes.length; i++) { 684 try { 685 checkMBeanPermission(classname, attributes[i], 686 name, "getAttribute"); 687 allowedList.add(attributes[i]); 688 } catch (SecurityException e) { 689 } 691 } 692 String [] allowedAttributes = 693 (String []) allowedList.toArray(new String [0]); 694 return meta.getAttributes(instance, allowedAttributes); 695 } else { 696 return meta.getAttributes(instance, attributes); 697 } 698 } 699 700 public void setAttribute(ObjectName name, Attribute attribute) 701 throws InstanceNotFoundException, AttributeNotFoundException, 702 InvalidAttributeValueException, MBeanException, 703 ReflectionException { 704 705 if (name == null) { 706 throw new RuntimeOperationsException(new 707 IllegalArgumentException ("ObjectName name cannot be null"), 708 "Exception occured trying to invoke the setter on the MBean"); 709 } 710 711 if (attribute == null) { 712 throw new RuntimeOperationsException(new 713 IllegalArgumentException ("Attribute cannot be null"), 714 "Exception occured trying to invoke the setter on the MBean"); 715 } 716 717 name = nonDefaultDomain(name); 718 719 if (isTraceOn()) { 720 trace("setAttribute", "Object= " + name + ", attribute=" + 721 attribute.getName()); 722 } 723 724 725 Object instance = getMBean(name); 726 String classname = null; 727 try { 728 classname = meta.getMBeanClassName(instance); 729 } catch (IntrospectionException e) { 730 classname = null; 731 } catch (NotCompliantMBeanException e) { 732 classname = null; 733 } 734 checkMBeanPermission(classname, attribute.getName(), 735 name, "setAttribute"); 736 737 final Object o = meta.setAttribute(instance, attribute); 738 } 739 740 public AttributeList setAttributes(ObjectName name, 741 AttributeList attributes) 742 throws InstanceNotFoundException, ReflectionException { 743 744 if (name == null) { 745 throw new RuntimeOperationsException(new 746 IllegalArgumentException ("ObjectName name cannot be null"), 747 "Exception occured trying to invoke the setter on the MBean"); 748 } 749 750 if (attributes == null) { 751 throw new RuntimeOperationsException(new 752 IllegalArgumentException ("AttributeList cannot be null"), 753 "Exception occured trying to invoke the setter on the MBean"); 754 } 755 756 name = nonDefaultDomain(name); 757 758 Object instance = getMBean(name); 759 SecurityManager sm = System.getSecurityManager(); 760 if (sm != null) { 761 762 String classname = null; 763 try { 764 classname = meta.getMBeanClassName(instance); 765 } catch (IntrospectionException e) { 766 classname = null; 767 } catch (NotCompliantMBeanException e) { 768 classname = null; 769 } 770 771 checkMBeanPermission(classname, null, name, "setAttribute"); 774 775 AttributeList allowedAttributes = 779 new AttributeList(attributes.size()); 780 for (Iterator i = attributes.iterator(); i.hasNext();) { 781 try { 782 Attribute attribute = (Attribute) i.next(); 783 checkMBeanPermission(classname, attribute.getName(), 784 name, "setAttribute"); 785 allowedAttributes.add(attribute); 786 } catch (SecurityException e) { 787 } 789 } 790 return meta.setAttributes(instance, allowedAttributes); 791 } else { 792 return meta.setAttributes(instance, attributes); 793 } 794 } 795 796 public Object invoke(ObjectName name, String operationName, 797 Object params[], String signature[]) 798 throws InstanceNotFoundException, MBeanException, 799 ReflectionException { 800 801 name = nonDefaultDomain(name); 802 803 804 Object instance = getMBean(name); 805 String classname = null; 806 try { 807 classname = meta.getMBeanClassName(instance); 808 } catch (IntrospectionException e) { 809 classname = null; 810 } catch (NotCompliantMBeanException e) { 811 classname = null; 812 } 813 checkMBeanPermission(classname, operationName, name, "invoke"); 814 815 return meta.invoke(instance, operationName, params, signature); 816 } 817 818 822 protected MetaData meta() { 823 return meta; 824 } 825 826 839 protected ObjectInstance makeObjectInstance(String className, 840 Object object, 841 ObjectName name) 842 throws NotCompliantMBeanException { 843 844 if (object instanceof DynamicMBean) { 847 try { 848 className = meta.getMBeanClassName(object); 849 } catch (SecurityException x) { 850 debugX("makeObjectInstance",x); 851 throw x; 852 } catch (IntrospectionException x) { 853 debugX("makeObjectInstance",x); 854 throw new NotCompliantMBeanException( 855 "Can't obtain class name for " + name + ": " + x); 856 } catch (JMRuntimeException x) { 857 debugX("makeObjectInstance",x); 858 throw new NotCompliantMBeanException( 859 "Can't obtain class name for " + name + ": " + x); 860 } 861 } 862 863 if (className == null) { 864 throw new NotCompliantMBeanException( 865 "The class Name returned is null"); 866 } 867 868 return(new ObjectInstance(nonDefaultDomain(name), className)); 869 } 870 871 901 protected ObjectInstance registerObject(String classname, 902 Object object, ObjectName name) 903 throws InstanceAlreadyExistsException, 904 MBeanRegistrationException, 905 NotCompliantMBeanException { 906 907 if (object == null) { 908 final RuntimeException wrapped = 909 new IllegalArgumentException ("Cannot add null object"); 910 throw new RuntimeOperationsException(wrapped, 911 "Exception occured trying to register the MBean"); 912 } 913 914 name = nonDefaultDomain(name); 915 916 if (isTraceOn()) { 917 trace(dbgTag, "registerMBean", "ObjectName = " + name); 918 } 919 920 ObjectName logicalName = name; 921 922 if (object instanceof MBeanRegistration) { 923 logicalName = meta.preRegisterInvoker(object, name, server); 924 if (logicalName != name && logicalName != null) { 925 logicalName = 926 ObjectName.getInstance(nonDefaultDomain(logicalName)); 927 } 928 } 929 930 931 checkMBeanPermission(classname, null, logicalName, "registerMBean"); 932 933 final ObjectInstance result; 934 if (logicalName!=null) { 935 result = makeObjectInstance(classname, object, logicalName); 936 internal_addObject(object, logicalName); 937 } else { 938 if (object instanceof MBeanRegistration ) { 939 meta.postRegisterInvoker(object, false); 940 } 941 final RuntimeException wrapped = 942 new IllegalArgumentException ("No object name specified"); 943 throw new RuntimeOperationsException(wrapped, 944 "Exception occured trying to register the MBean"); 945 } 946 947 if (object instanceof MBeanRegistration) 948 meta.postRegisterInvoker(object, true); 949 950 959 if (object instanceof ClassLoader ) { 960 final ModifiableClassLoaderRepository clr = 961 instantiator.getClassLoaderRepository(); 962 if (clr == null) { 963 final RuntimeException wrapped = 964 new IllegalArgumentException ( 965 "Dynamic addition of class loaders is not supported"); 966 throw new RuntimeOperationsException(wrapped, 967 "Exception occured trying to register the MBean as a class loader"); 968 } 969 clr.addClassLoader(logicalName, (ClassLoader )object); 970 } 971 972 return result; 973 } 974 975 982 protected ObjectInstance registerCreatedObject(String classname, 983 Object object, 984 ObjectName name) 985 throws InstanceAlreadyExistsException, 986 MBeanRegistrationException, 987 NotCompliantMBeanException { 988 return registerObject(classname,object,name); 989 } 990 991 995 private Object getMBean(ObjectName name) 996 throws InstanceNotFoundException { 997 998 if (name == null) { 999 throw new RuntimeOperationsException(new 1000 IllegalArgumentException ("Object name cannot be null"), 1001 "Exception occured trying to get an MBean"); 1002 } 1003 Object obj = null; 1004 synchronized(this) { 1005 obj = repository.retrieve(name); 1006 if (obj == null) { 1007 if (isTraceOn()) { 1008 trace("getMBean", name+": Found no object"); 1009 } 1010 throw new InstanceNotFoundException(name.toString()); 1011 } 1012 } 1013 return obj; 1014 } 1015 1016 private ObjectName nonDefaultDomain(ObjectName name) { 1017 if (name == null || name.getDomain().length() > 0) 1018 return name; 1019 1020 1027 final String completeName = domain + name; 1028 1029 try { 1030 return new ObjectName(completeName); 1031 } catch (MalformedObjectNameException e) { 1032 final String msg = 1033 "Unexpected default domain problem: " + completeName + ": " + 1034 e; 1035 throw new IllegalArgumentException (msg); 1036 } 1037 } 1038 1039 public String getDefaultDomain() { 1040 return domain; 1041 } 1042 1043 1087 public void addNotificationListener(ObjectName name, 1088 NotificationListener listener, 1089 NotificationFilter filter, 1090 Object handback) 1091 throws InstanceNotFoundException { 1092 1093 if (isTraceOn()) { 1096 trace("addNotificationListener", "obj= " + name); 1097 } 1098 1099 1100 Object instance = getMBean(name); 1101 String classname = null; 1102 try { 1103 classname = meta.getMBeanClassName(instance); 1104 } catch (IntrospectionException e) { 1105 classname = null; 1106 } catch (NotCompliantMBeanException e) { 1107 classname = null; 1108 } 1109 checkMBeanPermission(classname, null, name, "addNotificationListener"); 1110 1111 NotificationBroadcaster broadcaster; 1112 1113 if (!(instance instanceof NotificationBroadcaster)) { 1114 throw new RuntimeOperationsException(new 1115 IllegalArgumentException (name.getCanonicalName() ), 1116 "The MBean " + name.getCanonicalName() + 1117 " does not implement the NotificationBroadcaster interface"); 1118 } 1119 broadcaster = (NotificationBroadcaster) instance; 1120 1121 if (listener == null) { 1125 throw new RuntimeOperationsException(new 1126 IllegalArgumentException ("Null listener"),"Null listener"); 1127 } 1128 1129 NotificationListener listenerWrapper = 1130 getListenerWrapper(listener, name, instance, true); 1131 broadcaster.addNotificationListener(listenerWrapper, filter, handback); 1132 } 1133 1134 public void addNotificationListener(ObjectName name, 1135 ObjectName listener, 1136 NotificationFilter filter, 1137 Object handback) 1138 throws InstanceNotFoundException { 1139 1140 1143 Object instance = getMBean(listener); 1147 if (!(instance instanceof NotificationListener)) { 1148 throw new RuntimeOperationsException(new 1149 IllegalArgumentException (listener.getCanonicalName()), 1150 "The MBean " + listener.getCanonicalName() + 1151 "does not implement the NotificationListener interface") ; 1152 } 1153 1154 if (isTraceOn()) { 1158 trace("addNotificationListener", "obj= " + name + " listener= " + 1159 listener); 1160 } 1161 server.addNotificationListener(name,(NotificationListener) instance, 1162 filter, handback) ; 1163 } 1164 1165 public void removeNotificationListener(ObjectName name, 1166 NotificationListener listener) 1167 throws InstanceNotFoundException, ListenerNotFoundException { 1168 removeNotificationListener(name, listener, null, null, true); 1169 } 1170 1171 public void removeNotificationListener(ObjectName name, 1172 NotificationListener listener, 1173 NotificationFilter filter, 1174 Object handback) 1175 throws InstanceNotFoundException, ListenerNotFoundException { 1176 removeNotificationListener(name, listener, filter, handback, false); 1177 } 1178 1179 public void removeNotificationListener(ObjectName name, 1180 ObjectName listener) 1181 throws InstanceNotFoundException, ListenerNotFoundException { 1182 NotificationListener instance = getListener(listener); 1183 1184 if (isTraceOn()) { 1185 trace("removeNotificationListener", "obj= " + name + 1186 " listener= " + listener); 1187 } 1188 server.removeNotificationListener(name, instance); 1189 } 1190 1191 public void removeNotificationListener(ObjectName name, 1192 ObjectName listener, 1193 NotificationFilter filter, 1194 Object handback) 1195 throws InstanceNotFoundException, ListenerNotFoundException { 1196 1197 NotificationListener instance = getListener(listener); 1198 1199 if (isTraceOn()) { 1200 trace("removeNotificationListener", "obj= " + name + 1201 " listener= " + listener); 1202 } 1203 server.removeNotificationListener(name, instance, filter, handback); 1204 } 1205 1206 private NotificationListener getListener(ObjectName listener) 1207 throws ListenerNotFoundException { 1208 final Object instance; 1212 try { 1213 instance = getMBean(listener); 1214 } catch (InstanceNotFoundException e) { 1215 throw new ListenerNotFoundException(e.getMessage()) ; 1216 } 1217 1218 if (!(instance instanceof NotificationListener)) { 1219 final RuntimeException exc = 1220 new IllegalArgumentException (listener.getCanonicalName()); 1221 final String msg = 1222 "MBean " + listener.getCanonicalName() + " does not " + 1223 "implement " + NotificationListener.class.getName(); 1224 throw new RuntimeOperationsException(exc, msg); 1225 } 1226 return (NotificationListener) instance; 1227 } 1228 1229 private void removeNotificationListener(ObjectName name, 1230 NotificationListener listener, 1231 NotificationFilter filter, 1232 Object handback, 1233 boolean removeAll) 1234 throws InstanceNotFoundException, ListenerNotFoundException { 1235 1236 if (isTraceOn()) { 1237 trace("removeNotificationListener", "obj= " + name); 1238 } 1239 1240 1241 Object instance = getMBean(name); 1242 String classname = null; 1243 try { 1244 classname = meta.getMBeanClassName(instance); 1245 } catch (IntrospectionException e) { 1246 classname = null; 1247 } catch (NotCompliantMBeanException e) { 1248 classname = null; 1249 } 1250 checkMBeanPermission(classname, null, name, 1251 "removeNotificationListener"); 1252 1253 1257 NotificationBroadcaster broadcaster = null; 1258 NotificationEmitter emitter = null; 1259 if (removeAll) { 1260 if (!(instance instanceof NotificationBroadcaster)) { 1261 final RuntimeException exc = 1262 new IllegalArgumentException (name.getCanonicalName()); 1263 final String msg = 1264 "MBean " + name.getCanonicalName() + " does not " + 1265 "implement " + NotificationBroadcaster.class.getName(); 1266 throw new RuntimeOperationsException(exc, msg); 1267 } 1268 broadcaster = (NotificationBroadcaster) instance; 1269 } else { 1270 if (!(instance instanceof NotificationEmitter)) { 1271 final RuntimeException exc = 1272 new IllegalArgumentException (name.getCanonicalName()); 1273 final String msg = 1274 "MBean " + name.getCanonicalName() + " does not " + 1275 "implement " + NotificationEmitter.class.getName(); 1276 throw new RuntimeOperationsException(exc, msg); 1277 } 1278 emitter = (NotificationEmitter) instance; 1279 } 1280 1281 NotificationListener listenerWrapper = 1282 getListenerWrapper(listener, name, instance, false); 1283 1284 if (listenerWrapper == null) 1285 throw new ListenerNotFoundException("Unknown listener"); 1286 1287 if (removeAll) 1288 broadcaster.removeNotificationListener(listenerWrapper); 1289 else { 1290 emitter.removeNotificationListener(listenerWrapper, 1291 filter, 1292 handback); 1293 } 1294 } 1295 1296 public MBeanInfo getMBeanInfo(ObjectName name) 1297 throws InstanceNotFoundException, IntrospectionException, 1298 ReflectionException { 1299 1300 1303 Object moi = getMBean(name); 1304 final MBeanInfo mbi = meta.getMBeanInfo(moi); 1305 if (mbi == null) 1306 throw new JMRuntimeException("MBean " + name + 1307 "has no MBeanInfo"); 1308 1309 1310 checkMBeanPermission(mbi.getClassName(), null, name, "getMBeanInfo"); 1311 1312 return mbi; 1313 } 1314 1315 public boolean isInstanceOf(ObjectName name, String className) 1316 throws InstanceNotFoundException { 1317 1318 1319 Object instance = getMBean(name); 1320 String classname = null; 1321 try { 1322 classname = meta.getMBeanClassName(instance); 1323 } catch (IntrospectionException e) { 1324 classname = null; 1325 } catch (NotCompliantMBeanException e) { 1326 classname = null; 1327 } 1328 checkMBeanPermission(classname, null, name, "isInstanceOf"); 1329 1330 try { 1331 return meta.isInstanceOf(instance, className); 1332 } catch (ReflectionException e) { 1333 debugX("isInstanceOf",e); 1334 return false; 1335 } 1336 } 1337 1338 1345 public ClassLoader getClassLoaderFor(ObjectName mbeanName) 1346 throws InstanceNotFoundException { 1347 1348 1349 Object instance = getMBean(mbeanName); 1350 String classname = null; 1351 try { 1352 classname = meta.getMBeanClassName(instance); 1353 } catch (IntrospectionException e) { 1354 classname = null; 1355 } catch (NotCompliantMBeanException e) { 1356 classname = null; 1357 } 1358 checkMBeanPermission(classname, null, mbeanName, "getClassLoaderFor"); 1359 1360 return instance.getClass().getClassLoader(); 1361 } 1362 1363 1370 public ClassLoader getClassLoader(ObjectName loaderName) 1371 throws InstanceNotFoundException { 1372 1373 if (loaderName == null) { 1374 checkMBeanPermission(null, null, null, "getClassLoader"); 1375 return server.getClass().getClassLoader(); 1376 } 1377 1378 Object instance = getMBean(loaderName); 1379 String classname = null; 1380 try { 1381 classname = meta.getMBeanClassName(instance); 1382 } catch (IntrospectionException e) { 1383 classname = null; 1384 } catch (NotCompliantMBeanException e) { 1385 classname = null; 1386 } 1387 checkMBeanPermission(classname, null, loaderName, "getClassLoader"); 1388 1389 1390 if (!(instance instanceof ClassLoader )) 1391 throw new InstanceNotFoundException(loaderName.toString() + 1392 " is not a classloader"); 1393 1394 return (ClassLoader ) instance; 1395 } 1396 1397 1400 private void internal_addObject(Object object, ObjectName logicalName) 1401 throws InstanceAlreadyExistsException { 1402 1403 1406 1408 synchronized(this) { 1409 try { 1410 repository.addMBean(object, logicalName); 1411 } 1412 catch (InstanceAlreadyExistsException e) { 1413 if (object instanceof MBeanRegistration ) { 1414 meta.postRegisterInvoker(object,false); 1415 } 1416 throw e; 1417 } 1418 } 1419 if (isTraceOn()) { 1423 trace("addObject", "Send create notification of object " + 1424 logicalName.getCanonicalName()); 1425 } 1426 1427 sendNotification(MBeanServerNotification.REGISTRATION_NOTIFICATION, 1428 logicalName ) ; 1429 } 1430 1431 1435 private void sendNotification(String NotifType, ObjectName name) { 1436 1437 1440 MBeanServerNotification notif = new 1444 MBeanServerNotification(NotifType,_MBSDelegateObjectName,0,name); 1445 1446 if (isTraceOn()) { 1447 trace("sendNotification", NotifType + " " + name); 1448 } 1449 1450 delegate.sendNotification(notif); 1451 } 1452 1453 1458 private void initialize(String domain, 1459 MBeanServer outer, 1460 MBeanServerDelegate delegate, 1461 MBeanInstantiator inst, 1462 MetaData meta, 1463 Repository repos) { 1464 1465 1468 if (!this.domain.equals(repository.getDefaultDomain())) 1469 throw new IllegalArgumentException ("Domain Name Mismatch"); 1470 try { 1471 queryByRepo = repository.isFiltering(); 1472 } catch (SecurityException e) { 1473 throw e; 1474 } catch (Exception e) { 1475 queryByRepo = false; 1476 } 1477 } 1478 1479 1482 private Set filterListOfObjects(Set list, QueryExp query) { 1483 Set result = new HashSet (); 1484 1485 if (query == null ) { 1487 for (final Iterator i = list.iterator(); i.hasNext(); ) { 1488 final NamedObject no = (NamedObject) i.next(); 1489 final Object obj = no.getObject(); 1490 String className = null; 1491 1492 try { 1493 className = meta.getMBeanClassName(obj); 1494 } catch (JMException x) { 1495 if (isDebugOn()) { 1496 debug("filterListOfObjects", 1497 "Can't obtain class name for " + 1498 no.getName() + ": " + x); 1499 debugX("filterListOfObjects",x); 1500 } 1501 } 1502 1503 result.add(new ObjectInstance(no.getName(), className)); 1504 } 1505 } else { 1506 for (final Iterator i = list.iterator(); i.hasNext(); ) { 1508 final NamedObject no = (NamedObject) i.next(); 1509 final Object obj = no.getObject(); 1510 boolean res = false; 1511 MBeanServer oldServer = QueryEval.getMBeanServer(); 1512 query.setMBeanServer(server); 1513 try { 1514 res = query.apply(no.getName()); 1515 } catch (Exception e) { 1516 res = false; 1517 } finally { 1518 1527 query.setMBeanServer(oldServer); 1528 } 1529 if (res) { 1530 String className = null; 1533 try { 1534 className = meta.getMBeanClassName(obj); 1535 } catch (JMException x) { 1536 if (isDebugOn()) { 1537 debug("filterListOfObjects", 1538 "Can't obtain class name for " + 1539 no.getName() + ": " + x); 1540 debugX("filterListOfObjects",x); 1541 } 1542 } 1543 result.add(new ObjectInstance(no.getName(), className)); 1544 } 1545 } 1546 } 1547 return result; 1548 } 1549 1550 1553 private Set filterListOfObjectInstances(Set list, QueryExp query) { 1554 if (query == null) { 1557 return list; 1558 } else { 1559 Set result = new HashSet (); 1560 for (final Iterator i = list.iterator(); i.hasNext(); ) { 1563 final ObjectInstance oi = (ObjectInstance) i.next(); 1564 boolean res = false; 1565 MBeanServer oldServer = QueryEval.getMBeanServer(); 1566 query.setMBeanServer(server); 1567 try { 1568 res = query.apply(oi.getObjectName()); 1569 } catch (Exception e) { 1570 res = false; 1571 } finally { 1572 1581 query.setMBeanServer(oldServer); 1582 } 1583 if (res) { 1584 result.add(oi); 1585 } 1586 } 1587 return result; 1588 } 1589 } 1590 1591 1607 private NotificationListener getListenerWrapper(NotificationListener l, 1608 ObjectName name, 1609 Object mbean, 1610 boolean create) { 1611 NotificationListener wrapper = new ListenerWrapper(l, name, mbean); 1612 synchronized (listenerWrappers) { 1613 WeakReference ref = (WeakReference ) listenerWrappers.get(wrapper); 1614 if (ref != null) { 1615 NotificationListener existing = 1616 (NotificationListener) ref.get(); 1617 if (existing != null) 1618 return existing; 1619 } 1620 if (create) { 1621 listenerWrappers.put(wrapper, new WeakReference (wrapper)); 1622 return wrapper; 1623 } else 1624 return null; 1625 } 1626 } 1627 1628 private static class ListenerWrapper implements NotificationListener { 1629 ListenerWrapper(NotificationListener l, ObjectName name, 1630 Object mbean) { 1631 this.listener = l; 1632 this.name = name; 1633 this.mbean = mbean; 1634 } 1635 1636 public void handleNotification(Notification notification, 1637 Object handback) { 1638 if (notification != null) { 1639 if (notification.getSource() == mbean) 1640 notification.setSource(name); 1641 } 1642 1643 1652 listener.handleNotification(notification, handback); 1653 } 1654 1655 public boolean equals(Object o) { 1656 if (!(o instanceof ListenerWrapper)) 1657 return false; 1658 ListenerWrapper w = (ListenerWrapper) o; 1659 return (w.listener == listener && w.mbean == mbean 1660 && w.name.equals(name)); 1661 1669 } 1670 1671 public int hashCode() { 1672 return (System.identityHashCode(listener) ^ 1673 System.identityHashCode(mbean)); 1674 1686 } 1687 1688 private NotificationListener listener; 1689 private ObjectName name; 1690 private Object mbean; 1691 } 1692 1693 1696 private static void checkMBeanPermission(String classname, 1697 String member, 1698 ObjectName objectName, 1699 String actions) 1700 throws SecurityException { 1701 SecurityManager sm = System.getSecurityManager(); 1702 if (sm != null) { 1703 Permission perm = new MBeanPermission(classname, 1704 member, 1705 objectName, 1706 actions); 1707 sm.checkPermission(perm); 1708 } 1709 } 1710 1711 private static void checkMBeanTrustPermission(final Class theClass) 1712 throws SecurityException { 1713 SecurityManager sm = System.getSecurityManager(); 1714 if (sm != null) { 1715 Permission perm = new MBeanTrustPermission("register"); 1716 ProtectionDomain pd = (ProtectionDomain ) 1717 AccessController.doPrivileged(new PrivilegedAction () { 1718 public Object run() { 1719 return theClass.getProtectionDomain(); 1720 } 1721 }); 1722 AccessControlContext acc = 1723 new AccessControlContext (new ProtectionDomain [] { pd }); 1724 sm.checkPermission(perm, acc); 1725 } 1726 } 1727 1728 1731 private static boolean isTraceOn() { 1732 return Trace.isSelected(Trace.LEVEL_TRACE, Trace.INFO_MBEANSERVER); 1733 } 1734 1735 private static void trace(String clz, String func, String info) { 1736 Trace.send(Trace.LEVEL_TRACE, Trace.INFO_MBEANSERVER, clz, func, info); 1737 } 1738 1739 private static void trace(String func, String info) { 1740 trace(dbgTag, func, info); 1741 } 1742 1743 private static void error(String func, String info) { 1744 Trace.send(Trace.LEVEL_ERROR,Trace.INFO_MBEANSERVER,dbgTag,func,info); 1745 } 1746 1747 private static boolean isDebugOn() { 1748 return Trace.isSelected(Trace.LEVEL_DEBUG, Trace.INFO_MBEANSERVER); 1749 } 1750 1751 private static void debug(String clz, String func, String info) { 1752 Trace.send(Trace.LEVEL_DEBUG, Trace.INFO_MBEANSERVER, clz, func, info); 1753 } 1754 1755 private static void debug(String func, String info) { 1756 debug(dbgTag, func, info); 1757 } 1758 1759 private static void debugX(String func,Throwable e) { 1760 if (isDebugOn()) { 1761 final StringWriter s = new StringWriter (); 1762 e.printStackTrace(new PrintWriter (s)); 1763 final String stack = s.toString(); 1764 1765 debug(dbgTag,func,"Exception caught in "+ func+"(): "+e); 1766 debug(dbgTag,func,stack); 1767 1768 } 1772 } 1773} 1774 | Popular Tags |