0001: /* JFox, the OpenSource J2EE Application Server
0002: *
0003: * Copyright (C) 2002 huihoo.com
0004: * Distributable under GNU LGPL license
0005: * See the GNU Lesser General Public License for more details.
0006: */
0007:
0008: package org.huihoo.jfox.jmx;
0009:
0010: import java.util.Set;
0011: import java.util.Iterator;
0012: import java.util.HashSet;
0013: import java.util.ArrayList;
0014: import java.util.List;
0015: import java.util.Arrays;
0016: import javax.management.JMException;
0017: import javax.management.MBeanServerDelegate;
0018: import javax.management.ReflectionException;
0019: import javax.management.MBeanException;
0020: import javax.management.ObjectName;
0021: import javax.management.RuntimeOperationsException;
0022: import javax.management.InstanceNotFoundException;
0023: import javax.management.ObjectInstance;
0024: import javax.management.MBeanRegistration;
0025: import javax.management.MBeanRegistrationException;
0026: import javax.management.MBeanServerNotification;
0027: import javax.management.InstanceAlreadyExistsException;
0028: import javax.management.QueryExp;
0029: import javax.management.AttributeList;
0030: import javax.management.Attribute;
0031: import javax.management.NotificationListener;
0032: import javax.management.NotificationBroadcaster;
0033: import javax.management.MBeanInfo;
0034: import javax.management.ListenerNotFoundException;
0035: import javax.management.IntrospectionException;
0036: import javax.management.NotificationFilter;
0037: import javax.management.AttributeNotFoundException;
0038: import javax.management.InvalidAttributeValueException;
0039: import javax.management.NotCompliantMBeanException;
0040: import javax.management.MBeanServer;
0041: import javax.management.MBeanPermission;
0042: import javax.management.MalformedObjectNameException;
0043: import javax.management.NotificationEmitter;
0044: import javax.management.loading.ClassLoaderRepository;
0045: import javax.management.relation.MBeanServerNotificationFilter;
0046:
0047: import org.huihoo.jfox.jmx.loading.ExtendedClassLoaderRepository;
0048: import org.huihoo.jfox.jmx.loading.ClassLoaderRepositorySupport;
0049: import org.huihoo.jfox.jmx.interceptor.MBeanServerInterceptorListener;
0050:
0051: /**
0052: *
0053: * @author <a href="mailto:young_yy@hotmail.com">Young Yang</a>
0054: */
0055:
0056: public class MBeanServerSupport implements ExtendedMBeanServer {
0057:
0058: private String defaultDomain = null;
0059: // use MBeanServerRepositoryController to control MBeanServerRepository
0060: private MBeanServerRepositoryController repoctrl = null;//new MBeanServerRepositoryController(defaultDomain);
0061: // the class loader repository of the MBeanServer
0062: private ExtendedClassLoaderRepository loaderRepo = new ClassLoaderRepositorySupport();
0063: // private List listeners = new ArrayList();
0064:
0065: private MBeanIntrospector introspector = MBeanIntrospectorSupport
0066: .getInstance();
0067: private MBeanInstantiator instantiator = MBeanInstantiatorSupport
0068: .getInstance();
0069:
0070: private MBeanServerDelegate delegate = null;
0071: // A pointer to the MBeanServer object that must be passed to the MBeans when invoking their
0072: private MBeanServer outer = null;
0073:
0074: public MBeanServerSupport(String domain) {
0075: this (domain, null, new ExtendedMBeanServerDelegate());
0076: }
0077:
0078: public MBeanServerSupport(String domain, MBeanServer outer,
0079: MBeanServerDelegate delegate) {
0080: this .defaultDomain = domain;
0081: if (outer == null)
0082: outer = this ;
0083: this .outer = outer;
0084: repoctrl = new MBeanServerRepositoryController(outer);
0085: // repoctrl.setDomain(domain);
0086: this .delegate = delegate;
0087: try {
0088: registerMBean(delegate, ExtendedMBeanServerDelegate
0089: .getObjectName());
0090: } catch (JMException e) {
0091: e.printStackTrace();
0092: }
0093: }
0094:
0095: public Object instantiate(String className)
0096: throws ReflectionException, MBeanException {
0097: return instantiate(className, null, null);
0098: }
0099:
0100: public Object instantiate(String className, ObjectName loaderName)
0101: throws ReflectionException, MBeanException,
0102: InstanceNotFoundException {
0103: return instantiate(className, loaderName, null, null);
0104: }
0105:
0106: /**
0107: *
0108: * @param className The class name of the object to be instantiated.
0109: * @param params An array containing the parameters of the constructor to be invoked.
0110: * @param signatures An array containing the signature of the constructor to be invoked
0111: * @return The newly instantiated object.
0112: * @throws ReflectionException Wraps a java.lang.ClassNotFoundException or the java.lang.Exception that occurred when trying to reflectInvoke the object's constructor.
0113: * @throws MBeanException Wraps a java.lang.IllegalArgumentException: The className passed in parameter is null.
0114: */
0115: public Object instantiate(String className, Object params[],
0116: String signatures[]) throws ReflectionException,
0117: MBeanException {
0118: if (className == null || className.trim().length() == 0)
0119: throw new RuntimeOperationsException(
0120: new IllegalArgumentException(
0121: "Class name cannot be null or empty"));
0122: Class mbeanClass = null;
0123: try {
0124: mbeanClass = loaderRepo.loadClass(className);
0125: } catch (ClassNotFoundException e) {
0126: throw new ReflectionException(e, e.toString());
0127: }
0128: PermissionChecker.checkMBeanPermission(className, null, null,
0129: MBeanPermission.Instantiate);
0130: // MBeanIntrospector introspector = new MBeanIntrospectorSupport(mbeanClass);
0131: introspector.checkInstantiate(mbeanClass); // only check the constructor for instantiate, not check compliance
0132:
0133: Object obj = instantiator.instantiate(mbeanClass, params,
0134: signatures);
0135: return obj;
0136: }
0137:
0138: public Object instantiate(String className, ObjectName loaderName,
0139: Object params[], String signatures[])
0140: throws ReflectionException, MBeanException,
0141: InstanceNotFoundException {
0142: // loadName is null, user the System classLoader
0143: if (loaderName == null || !repoctrl.contains(loaderName))
0144: return instantiate(className, params, signatures);
0145:
0146: if (className == null || className.trim().length() == 0)
0147: throw new RuntimeOperationsException(
0148: new IllegalArgumentException(
0149: "Class name cannot be null or empty"));
0150: Class mbeanClass = null;
0151: ClassLoader loader = null;
0152: if (loaderName == null)
0153: loader = this .getClass().getClassLoader();
0154: else {
0155: Object obj = repoctrl.retrieve(loaderName).getMBeanObject();
0156: if (!(obj instanceof ClassLoader)) // not a MLetRI or other ClassLoader MBean
0157: throw new InstanceNotFoundException(
0158: "The MBean is not a ClassLoader: "
0159: + loaderName.toString());
0160: loader = (ClassLoader) obj;
0161: }
0162: try {
0163: mbeanClass = loader.loadClass(className);
0164: // load signature class
0165: } catch (ClassNotFoundException e) {
0166: throw new ReflectionException(e, e.toString());
0167: }
0168: // MBeanIntrospector introspector = new MBeanIntrospectorSupport(mbeanClass);
0169: introspector.checkInstantiate(mbeanClass); // only check the constructor for instantiate, not check compliance
0170:
0171: Object obj = instantiator.instantiate(mbeanClass, params,
0172: signatures);
0173: return obj;
0174: }
0175:
0176: public ObjectInstance createMBean(String className,
0177: ObjectName objectName) throws ReflectionException,
0178: InstanceAlreadyExistsException, MBeanRegistrationException,
0179: MBeanException, NotCompliantMBeanException {
0180: return createMBean(className, objectName, null, null);
0181: }
0182:
0183: public ObjectInstance createMBean(String className,
0184: ObjectName objectName, ObjectName loaderName)
0185: throws ReflectionException, InstanceAlreadyExistsException,
0186: MBeanRegistrationException, MBeanException,
0187: NotCompliantMBeanException, InstanceNotFoundException {
0188: return createMBean(className, objectName, loaderName, null,
0189: null);
0190: }
0191:
0192: public ObjectInstance createMBean(String className,
0193: ObjectName objectName, Object[] params, String[] signatures)
0194: throws ReflectionException, InstanceAlreadyExistsException,
0195: MBeanRegistrationException, MBeanException,
0196: NotCompliantMBeanException {
0197: // if(DEFAULT_OBJECTNAME.isPattern()) throw new RuntimeOperationsException(new IllegalArgumentException("ObjectName " + DEFAULT_OBJECTNAME.toString() + " is a pattern object name"));
0198: // if(repoctrl.contains(DEFAULT_OBJECTNAME)) throw new InstanceAlreadyExistsException(DEFAULT_OBJECTNAME.toString());
0199:
0200: Object obj = instantiate(className, params, signatures);
0201: return registerMBean(obj, objectName);
0202:
0203: }
0204:
0205: public ObjectInstance createMBean(String className,
0206: ObjectName objectName, ObjectName loaderName,
0207: Object[] params, String[] signatures)
0208: throws ReflectionException, InstanceAlreadyExistsException,
0209: MBeanRegistrationException, MBeanException,
0210: NotCompliantMBeanException, InstanceNotFoundException {
0211: // if(DEFAULT_OBJECTNAME.isPattern()) throw new RuntimeOperationsException(new IllegalArgumentException("ObjectName " + DEFAULT_OBJECTNAME.toString() + " is a pattern object name"));
0212: // if(repoctrl.contains(DEFAULT_OBJECTNAME)) throw new InstanceAlreadyExistsException(DEFAULT_OBJECTNAME.toString());
0213:
0214: Object obj = instantiate(className, loaderName, params,
0215: signatures);
0216:
0217: return registerMBean(obj, objectName);
0218: }
0219:
0220: public ObjectInstance registerMBean(Object obj,
0221: ObjectName objectName)
0222: throws InstanceAlreadyExistsException,
0223: MBeanRegistrationException, NotCompliantMBeanException {
0224: boolean isRegisterMBean = (obj instanceof MBeanRegistration) ? true
0225: : false;
0226:
0227: PermissionChecker.checkMBeanPermission(
0228: obj.getClass().getName(), null, objectName,
0229: MBeanPermission.RegisterMBean);
0230: PermissionChecker.checkMBeanTrustPermission(obj.getClass());
0231:
0232: // preRegister
0233: if (isRegisterMBean) {
0234: try {
0235: if (objectName != null)
0236: objectName = repoctrl
0237: .getCompleteObjectName(objectName);
0238: ObjectName registerObjectName = ((MBeanRegistration) obj)
0239: .preRegister(outer, objectName);
0240: if (objectName == null)
0241: objectName = registerObjectName; // use the ObjectName return by preRegister
0242: } catch (Exception e) {
0243: try {
0244: ((MBeanRegistration) obj)
0245: .postRegister(Boolean.FALSE);
0246: } catch (Exception ex) {
0247: throw new MBeanRegistrationException(ex, ex
0248: .toString());
0249: }
0250: throw new MBeanRegistrationException(e, e.toString());
0251: }
0252: }
0253:
0254: if (objectName == null)
0255: throw new RuntimeOperationsException(
0256: new IllegalArgumentException(
0257: "ObjectName is null ,but not implements MBeanRegistry"));
0258: if (objectName.isPattern())
0259: throw new RuntimeOperationsException(
0260: new IllegalArgumentException("ObjectName "
0261: + objectName.toString()
0262: + " is a pattern object name"));
0263:
0264: if (repoctrl.contains(objectName))
0265: throw new InstanceAlreadyExistsException(objectName
0266: .toString());
0267:
0268: Class interfaceClass = introspector.checkCompliance(obj
0269: .getClass()); // check compliance with jmx spe.
0270: MBeanMetaData meta = MBeanMetaDataFactory
0271: .getInstance(
0272: repoctrl.getCompleteObjectName(objectName),
0273: obj, interfaceClass);
0274:
0275: repoctrl.store(objectName, meta); // store to repository
0276: // send registration notification
0277: sendInterceptorNotification(
0278: MBeanServerNotification.REGISTRATION_NOTIFICATION,
0279: objectName,
0280: ExtendedMBeanServerNotification.REGISTER_MBEAN,
0281: new Object[] { obj });
0282: // add classloader to loader repository
0283: if (obj instanceof ClassLoader) {
0284: loaderRepo.addClassLoader((ClassLoader) obj);
0285: }
0286:
0287: // postRegister
0288: if (isRegisterMBean) {
0289: try {
0290: ((MBeanRegistration) obj).postRegister(Boolean.TRUE);
0291: } catch (Exception e) {
0292: throw new MBeanRegistrationException(e);
0293: }
0294: }
0295:
0296: return meta.getObjectInstance();
0297: }
0298:
0299: public void unregisterMBean(ObjectName objectName)
0300: throws InstanceNotFoundException,
0301: MBeanRegistrationException {
0302: if (objectName.isPattern())
0303: throw new RuntimeOperationsException(
0304: new IllegalArgumentException("ObjectName "
0305: + objectName.toString()
0306: + " is a pattern object name"));
0307: if (objectName == null)
0308: throw new RuntimeOperationsException(
0309: new IllegalArgumentException(
0310: "Object name cannot be null"));
0311:
0312: if (!repoctrl.contains(objectName))
0313: throw new InstanceNotFoundException(objectName.toString());
0314: // can't unregister MBeanServerDelegate
0315: if (objectName.equals(ExtendedMBeanServerDelegate
0316: .getObjectName()))
0317: throw new RuntimeOperationsException(
0318: new IllegalArgumentException(
0319: "The MBeanDelegate MBean cannot be unregistered"));
0320:
0321: MBeanMetaData meta = repoctrl.retrieve(objectName);
0322: PermissionChecker.checkMBeanPermission(meta.getClassName(),
0323: null, objectName, MBeanPermission.UnregisterMBean);
0324:
0325: Object obj = meta.getMBeanObject();
0326: boolean isRegisterMBean = false;
0327: if (obj instanceof MBeanRegistration)
0328: isRegisterMBean = true;
0329:
0330: if (isRegisterMBean) {
0331: try {
0332: ((MBeanRegistration) obj).preDeregister();
0333: } catch (Exception e) {
0334: try {
0335: ((MBeanRegistration) obj).postDeregister();
0336: } catch (Exception ex) {
0337: throw new MBeanRegistrationException(ex);
0338: }
0339: throw new MBeanRegistrationException(e);
0340: }
0341: }
0342:
0343: repoctrl.remove(objectName); // remove from repository
0344:
0345: // send unregistration notification
0346: sendInterceptorNotification(
0347: MBeanServerNotification.UNREGISTRATION_NOTIFICATION,
0348: objectName,
0349: ExtendedMBeanServerNotification.UNREGISTER_MBEAN, null);
0350:
0351: // remove classloader from loader repository
0352: if (obj instanceof ClassLoader) {
0353: loaderRepo.removeClassLoader((ClassLoader) obj);
0354: }
0355:
0356: if (isRegisterMBean) {
0357: try {
0358: ((MBeanRegistration) obj).postDeregister();
0359: } catch (Exception e) {
0360: throw new MBeanRegistrationException(e);
0361: }
0362: }
0363:
0364: }
0365:
0366: public ObjectInstance getObjectInstance(ObjectName objectName)
0367: throws InstanceNotFoundException {
0368: if (objectName == null)
0369: throw new RuntimeOperationsException(
0370: new IllegalArgumentException(
0371: "Object name cannot be null"));
0372: if (!repoctrl.contains(objectName))
0373: throw new InstanceNotFoundException(objectName.toString());
0374:
0375: MBeanMetaData meta = repoctrl.retrieve(objectName);
0376:
0377: PermissionChecker.checkMBeanPermission(meta.getClassName(),
0378: null, objectName, MBeanPermission.GetObjectInstance);
0379:
0380: sendInterceptorNotification(
0381: ExtendedMBeanServerNotification.GET_OBJECTINSTANCE_NOTIFICATION,
0382: objectName,
0383: ExtendedMBeanServerNotification.GET_OBJECTINSTANCE,
0384: null);
0385: return meta.getObjectInstance();
0386: }
0387:
0388: public Set queryMBeans(ObjectName objectName, QueryExp query) {
0389: // if(DEFAULT_OBJECTNAME == null) throw new RuntimeOperationsException(new IllegalArgumentException("Object name cannot be null"));
0390: PermissionChecker.checkMBeanPermission(null, null, null,
0391: MBeanPermission.QueryMBeans);
0392:
0393: Set set = repoctrl.queryMBeans(objectName, query);
0394: Set vset = new HashSet();
0395: for (Iterator iter = set.iterator(); iter.hasNext();) {
0396: try {
0397: ObjectInstance oi = (ObjectInstance) iter.next();
0398: PermissionChecker.checkMBeanPermission(oi
0399: .getClassName(), null, oi.getObjectName(),
0400: MBeanPermission.QueryMBeans);
0401: vset.add(oi);
0402: } catch (SecurityException e) {
0403: e.printStackTrace();
0404: // Do not add this ObjectInstance to the list
0405: }
0406: }
0407:
0408: sendInterceptorNotification(
0409: ExtendedMBeanServerNotification.QUERYMBEANS_NOTIFICATION,
0410: objectName,
0411: ExtendedMBeanServerNotification.QUERY_MBEANS,
0412: new Object[] { query });
0413: return vset;
0414: }
0415:
0416: public Set queryNames(ObjectName objectName, QueryExp query) {
0417: PermissionChecker.checkMBeanPermission(null, null, null,
0418: MBeanPermission.QueryNames);
0419: Set set = repoctrl.queryMBeans(objectName, query);
0420: Set vset = new HashSet();
0421: for (Iterator iter = set.iterator(); iter.hasNext();) {
0422: try {
0423: ObjectInstance instance = (ObjectInstance) iter.next();
0424: PermissionChecker.checkMBeanPermission(instance
0425: .getClassName(), null,
0426: instance.getObjectName(),
0427: MBeanPermission.QueryNames);
0428: // System.out.println("Add ObjectName: " + instance.getObjectName());
0429: vset.add(instance.getObjectName());
0430: } catch (SecurityException e) {
0431: e.printStackTrace();
0432: }
0433: }
0434: return vset;
0435: }
0436:
0437: public boolean isRegistered(ObjectName objectName) {
0438: if (objectName == null)
0439: throw new RuntimeOperationsException(
0440: new IllegalArgumentException(
0441: "Object name cannot be null"));
0442: sendInterceptorNotification(
0443: ExtendedMBeanServerNotification.ISREGISTERED_NOTIFICATION,
0444: objectName,
0445: ExtendedMBeanServerNotification.ISREGISTERED, null);
0446: return repoctrl.contains(objectName);
0447: }
0448:
0449: public Integer getMBeanCount() {
0450: return new Integer(repoctrl.getRepoSize());
0451: }
0452:
0453: public Object getAttribute(ObjectName objectName, String attribute)
0454: throws MBeanException, AttributeNotFoundException,
0455: InstanceNotFoundException, ReflectionException {
0456: if (objectName == null)
0457: throw new RuntimeOperationsException(
0458: new IllegalArgumentException(
0459: "Object name cannot be null"));
0460: if (attribute == null || attribute.trim().length() == 0)
0461: throw new RuntimeOperationsException(
0462: new IllegalArgumentException(
0463: "attribute name cannot be null or empty"));
0464: if (!repoctrl.contains(objectName))
0465: throw new InstanceNotFoundException(objectName.toString());
0466: MBeanMetaData meta = repoctrl.retrieve(objectName);
0467: PermissionChecker.checkMBeanPermission(meta.getClassName(),
0468: attribute, objectName, MBeanPermission.GetAttribute);
0469: sendInterceptorNotification(
0470: ExtendedMBeanServerNotification.GET_ATTRIBUTE_NOTIFICATION,
0471: objectName,
0472: ExtendedMBeanServerNotification.GET_ATTRIBUTE,
0473: new String[] { attribute });
0474: // return instantiator.getAttribute(meta,attribute);
0475: return meta.getAttribute(attribute);
0476:
0477: }
0478:
0479: public AttributeList getAttributes(ObjectName objectName,
0480: String attributes[]) throws InstanceNotFoundException,
0481: ReflectionException {
0482: if (objectName == null)
0483: throw new RuntimeOperationsException(
0484: new IllegalArgumentException(
0485: "Object name cannot be null"));
0486: if (attributes == null)
0487: throw new RuntimeOperationsException(
0488: new IllegalArgumentException(
0489: "attributes array cannot be null"));
0490: if (!repoctrl.contains(objectName))
0491: throw new InstanceNotFoundException(objectName.toString());
0492:
0493: MBeanMetaData meta = repoctrl.retrieve(objectName);
0494:
0495: PermissionChecker.checkMBeanPermission(meta.getClassName(),
0496: null, objectName, MBeanPermission.GetAttribute);
0497: List vattributes = Arrays.asList(attributes);
0498: if (System.getSecurityManager() != null) {
0499: for (int i = 0; i < attributes.length; i++) {
0500: try {
0501: PermissionChecker.checkMBeanPermission(meta
0502: .getClassName(), attributes[i], objectName,
0503: MBeanPermission.SetAttribute);
0504:
0505: } catch (SecurityException e) {
0506: vattributes.remove(attributes[i]);
0507: }
0508: }
0509: }
0510:
0511: sendInterceptorNotification(
0512: ExtendedMBeanServerNotification.GET_ATTRIBUTES_NOTIFICATION,
0513: objectName,
0514: ExtendedMBeanServerNotification.GET_ATTRIBUTES,
0515: attributes);
0516: try {
0517: return meta.getAttributes((String[]) vattributes
0518: .toArray(new String[0]));
0519: } catch (Exception e) {
0520: throw new ReflectionException(e, e.toString());
0521: }
0522: }
0523:
0524: public void setAttribute(ObjectName objectName, Attribute attribute)
0525: throws InstanceNotFoundException,
0526: AttributeNotFoundException, InvalidAttributeValueException,
0527: MBeanException, ReflectionException {
0528: if (objectName == null)
0529: throw new RuntimeOperationsException(
0530: new IllegalArgumentException(
0531: "Object name cannot be null"));
0532: if (attribute == null
0533: || attribute.getName().trim().length() == 0)
0534: throw new RuntimeOperationsException(
0535: new IllegalArgumentException(
0536: "attribute name cannot be null or empty"));
0537: if (!repoctrl.contains(objectName))
0538: throw new InstanceNotFoundException(objectName.toString());
0539:
0540: MBeanMetaData meta = repoctrl.retrieve(objectName);
0541: PermissionChecker.checkMBeanPermission(meta.getClassName(),
0542: attribute.getName(), objectName,
0543: MBeanPermission.SetAttribute);
0544:
0545: sendInterceptorNotification(
0546: ExtendedMBeanServerNotification.SET_ATTRIBUTE_NOTIFICATION,
0547: objectName,
0548: ExtendedMBeanServerNotification.SET_ATTRIBUTE,
0549: new Object[] { attribute });
0550: meta.setAttribute(attribute);
0551:
0552: }
0553:
0554: public AttributeList setAttributes(ObjectName objectName,
0555: AttributeList attributes) throws InstanceNotFoundException,
0556: ReflectionException {
0557: if (objectName == null)
0558: throw new RuntimeOperationsException(
0559: new IllegalArgumentException(
0560: "Object name cannot be null"));
0561: if (attributes == null)
0562: throw new RuntimeOperationsException(
0563: new IllegalArgumentException(
0564: "AttributeList cannot be null"),
0565: "Exception occured trying to reflectInvoke the setter on the MBean");
0566: if (attributes.isEmpty())
0567: return attributes;
0568: if (!repoctrl.contains(objectName))
0569: throw new InstanceNotFoundException(objectName.toString());
0570: MBeanMetaData meta = repoctrl.retrieve(objectName);
0571:
0572: PermissionChecker.checkMBeanPermission(meta.getClassName(),
0573: null, objectName, MBeanPermission.SetAttribute);
0574:
0575: AttributeList vattributes = new AttributeList(attributes);
0576: if (System.getSecurityManager() != null) {
0577: for (Iterator iter = attributes.iterator(); iter.hasNext();) {
0578: Attribute attribute = (Attribute) iter.next();
0579: try {
0580: PermissionChecker.checkMBeanPermission(meta
0581: .getClassName(), attribute.getName(),
0582: objectName, MBeanPermission.SetAttribute);
0583: } catch (SecurityException e) {
0584: vattributes.remove(attribute);
0585: }
0586: }
0587:
0588: }
0589:
0590: sendInterceptorNotification(
0591: ExtendedMBeanServerNotification.SET_ATTRIBUTES_NOTIFICATION,
0592: objectName,
0593: ExtendedMBeanServerNotification.SET_ATTRIBUTES,
0594: new Object[] { attributes });
0595: try {
0596: return meta.setAttributes(vattributes);
0597:
0598: } catch (Exception e) {
0599: throw new ReflectionException(e, e.toString());
0600: }
0601:
0602: }
0603:
0604: public Object invoke(ObjectName objectName, String operationName,
0605: Object params[], String signatures[])
0606: throws InstanceNotFoundException, MBeanException,
0607: ReflectionException {
0608: // System.out.println(DEFAULT_OBJECTNAME);
0609: if (objectName == null)
0610: throw new RuntimeOperationsException(
0611: new IllegalArgumentException(
0612: "Object name cannot be null"));
0613: if (operationName == null || operationName.trim().length() == 0)
0614: throw new RuntimeOperationsException(
0615: new IllegalArgumentException(
0616: "operation name cannot be null or empty"));
0617: if (!repoctrl.contains(objectName))
0618: throw new InstanceNotFoundException(objectName.toString());
0619:
0620: MBeanMetaData meta = repoctrl.retrieve(objectName);
0621: PermissionChecker.checkMBeanPermission(meta.getClassName(),
0622: operationName, objectName, MBeanPermission.Invoke);
0623: sendInterceptorNotification(
0624: ExtendedMBeanServerNotification.INVOKE_NOTIFICATION,
0625: objectName, ExtendedMBeanServerNotification.INVOKE,
0626: new Object[] { operationName, signatures });
0627: // return instantiator.invoke(meta,operationName,params,signatures);
0628: return meta.invoke(operationName, params, signatures);
0629: }
0630:
0631: public String getDefaultDomain() {
0632: return defaultDomain;
0633: }
0634:
0635: public void addNotificationListener(ObjectName objectName,
0636: NotificationListener listener, NotificationFilter filter,
0637: Object handback) throws InstanceNotFoundException {
0638: if (objectName == null)
0639: throw new RuntimeOperationsException(
0640: new IllegalArgumentException(
0641: "Object name cannot be null"));
0642: if (listener == null)
0643: throw new RuntimeOperationsException(
0644: new IllegalArgumentException(
0645: "NotificationListener cannot be null"));
0646: if (!repoctrl.contains(objectName))
0647: throw new InstanceNotFoundException(objectName.toString());
0648:
0649: MBeanMetaData meta = repoctrl.retrieve(objectName);
0650: PermissionChecker.checkMBeanPermission(meta.getClassName(),
0651: null, objectName,
0652: MBeanPermission.AddNotificationListener);
0653:
0654: Object mbean = meta.getMBeanObject();
0655: if (!(mbean instanceof NotificationBroadcaster))
0656: throw new InstanceNotFoundException("ObjectName "
0657: + objectName + " is not a NotificationBroadcaster");
0658:
0659: sendInterceptorNotification(
0660: ExtendedMBeanServerNotification.ADD_NOTIFICATIONLISTENER_NOTIFICATION,
0661: objectName,
0662: ExtendedMBeanServerNotification.ADD_NOTIFICATIONLISTENER_NOTIFICATION,
0663: new Object[] { listener, filter, handback });
0664: ((NotificationBroadcaster) mbean).addNotificationListener(
0665: listener, filter, handback);
0666: }
0667:
0668: public void addNotificationListener(ObjectName objectName,
0669: ObjectName listenerName, NotificationFilter filter,
0670: Object handback) throws InstanceNotFoundException {
0671: if (objectName == null)
0672: throw new RuntimeOperationsException(
0673: new IllegalArgumentException(
0674: "Object name cannot be null"));
0675: if (listenerName == null)
0676: throw new RuntimeOperationsException(
0677: new IllegalArgumentException(
0678: "Object name cannot be null"));
0679: if (!repoctrl.contains(objectName))
0680: throw new InstanceNotFoundException(objectName.toString());
0681: if (!repoctrl.contains(listenerName))
0682: throw new InstanceNotFoundException(listenerName.toString());
0683: Object listener = repoctrl.retrieve(listenerName)
0684: .getMBeanObject();
0685: if (!(listener instanceof NotificationListener))
0686: throw new InstanceNotFoundException("ObjectName "
0687: + listenerName + " is not a NotificationListener");
0688:
0689: this .addNotificationListener(objectName,
0690: (NotificationListener) listener, filter, handback);
0691: }
0692:
0693: public void removeNotificationListener(ObjectName objectName,
0694: NotificationListener listener)
0695: throws InstanceNotFoundException, ListenerNotFoundException {
0696: if (objectName == null)
0697: throw new RuntimeOperationsException(
0698: new IllegalArgumentException(
0699: "Object name cannot be null"));
0700: if (listener == null)
0701: throw new RuntimeOperationsException(
0702: new IllegalArgumentException(
0703: "NotificationListener cannot be null"));
0704: if (!repoctrl.contains(objectName))
0705: throw new InstanceNotFoundException(objectName.toString());
0706:
0707: MBeanMetaData meta = repoctrl.retrieve(objectName);
0708: PermissionChecker.checkMBeanPermission(meta.getClassName(),
0709: null, objectName,
0710: MBeanPermission.RemoveNotificationListener);
0711:
0712: Object mbean = meta.getMBeanObject();
0713: if (!(mbean instanceof NotificationBroadcaster))
0714: throw new InstanceNotFoundException("ObjectName "
0715: + objectName + " is not a NotificationBroadcaster");
0716:
0717: sendInterceptorNotification(
0718: ExtendedMBeanServerNotification.REMOVE_NOTIFICATIONLISTENER_NOTIFICATION,
0719: objectName,
0720: ExtendedMBeanServerNotification.REMOVE_NOTIFICATION_LISTENER,
0721: new Object[] { listener });
0722: ((NotificationBroadcaster) mbean)
0723: .removeNotificationListener(listener);
0724: }
0725:
0726: public void removeNotificationListener(ObjectName objectName,
0727: ObjectName listenerName) throws InstanceNotFoundException,
0728: ListenerNotFoundException {
0729: if (objectName == null)
0730: throw new RuntimeOperationsException(
0731: new IllegalArgumentException(
0732: "Object name cannot be null"));
0733: if (listenerName == null)
0734: throw new RuntimeOperationsException(
0735: new IllegalArgumentException(
0736: "Object name cannot be null"));
0737: if (!repoctrl.contains(objectName))
0738: throw new InstanceNotFoundException(objectName.toString());
0739: if (!repoctrl.contains(listenerName))
0740: throw new InstanceNotFoundException(listenerName.toString());
0741: Object listener = repoctrl.retrieve(listenerName);
0742: if (!(listener instanceof NotificationListener))
0743: throw new InstanceNotFoundException("ObjectName "
0744: + listenerName + " is not a NotificationListener");
0745:
0746: this .removeNotificationListener(objectName,
0747: (NotificationListener) listener);
0748: }
0749:
0750: public MBeanInfo getMBeanInfo(ObjectName objectName)
0751: throws InstanceNotFoundException, IntrospectionException,
0752: ReflectionException {
0753: if (objectName == null)
0754: throw new RuntimeOperationsException(
0755: new IllegalArgumentException(
0756: "Object name cannot be null"));
0757: if (!repoctrl.contains(objectName))
0758: throw new InstanceNotFoundException(objectName.toString());
0759: MBeanMetaData meta = repoctrl.retrieve(objectName);
0760: PermissionChecker.checkMBeanPermission(meta.getClassName(),
0761: null, objectName, MBeanPermission.GetMBeanInfo);
0762: sendInterceptorNotification(
0763: ExtendedMBeanServerNotification.GET_MBEANINFO_NOTIFICATION,
0764: objectName,
0765: ExtendedMBeanServerNotification.GET_MBEANINFO, null);
0766: return meta.getMBeanInfo();
0767: }
0768:
0769: public boolean isInstanceOf(ObjectName objectName, String className)
0770: throws InstanceNotFoundException {
0771: if (objectName == null)
0772: throw new RuntimeOperationsException(
0773: new IllegalArgumentException(
0774: "Object name cannot be null"));
0775: if (!repoctrl.contains(objectName))
0776: throw new InstanceNotFoundException(objectName.toString());
0777:
0778: MBeanMetaData meta = repoctrl.retrieve(objectName);
0779: PermissionChecker.checkMBeanPermission(meta.getClassName(),
0780: null, objectName, MBeanPermission.IsInstanceOf);
0781:
0782: sendInterceptorNotification(
0783: ExtendedMBeanServerNotification.ISINSTANCEOF_NOTIFICATION,
0784: objectName,
0785: ExtendedMBeanServerNotification.IS_INSTANCEOF,
0786: new Object[] { className });
0787: try {
0788: Class _class = loaderRepo.loadClass(className);
0789: return _class.isInstance(meta.getMBeanObject());
0790: } catch (ClassNotFoundException e) {
0791: e.printStackTrace();
0792: }
0793:
0794: return false;
0795: }
0796:
0797: /*
0798: public ObjectInputStream deserialize(ObjectName loaderName, byte[] bytes) throws InstanceNotFoundException, OperationsException {
0799: if(loaderName == null) throw new RuntimeOperationsException(new IllegalArgumentException("Object name cannot be null"));
0800: if(bytes == null || bytes.length == 0)
0801: throw new RuntimeOperationsException(new IllegalArgumentException(), "byte array parameter cannot be null or empty");
0802:
0803: if(!repoctrl.contains(loaderName)) throw new InstanceNotFoundException(loaderName.toString());
0804:
0805: delegate.sendNotification(ExtendedMBeanServerNotification.DESERIALIZE_NOTIFICATION,loaderName,ExtendedMBeanServerNotification.DESERIALIZE,new Object[]{bytes});
0806:
0807: ClassLoader loader = repoctrl.retrieve(loaderName).getClassLoader();
0808:
0809: ByteArrayInputStream byteInput = new ByteArrayInputStream(bytes);
0810: ObjectInputStreamLoader objectLoader = null;
0811: try {
0812: objectLoader = new ObjectInputStreamLoader(byteInput, loader);
0813: }
0814: catch(IOException e) {
0815: throw new OperationsException("deserialize error: " + e.toString());
0816: }
0817: return objectLoader;
0818: }
0819:
0820: public ObjectInputStream deserialize(String className, byte[] bytes) throws OperationsException, ReflectionException {
0821: if(className == null || className.trim().length() == 0) {throw new RuntimeOperationsException(new IllegalArgumentException("Invalid class name"));}
0822: if(bytes == null || bytes.length == 0)
0823: throw new RuntimeOperationsException(new IllegalArgumentException(), "byte array parameter cannot be null or empty");
0824:
0825: ClassLoader loader = null;
0826: try {
0827: Class c = loaderRepo.loadClass(className);
0828: loader = c.getClassLoader();
0829: }
0830: catch(ClassNotFoundException e){
0831: throw new ReflectionException(e, e.toString());
0832: }
0833: ObjectInputStreamLoader objectLoader = null;
0834: ByteArrayInputStream byteInput = new ByteArrayInputStream(bytes);
0835: try {
0836: objectLoader = new ObjectInputStreamLoader(byteInput, loader);
0837: }
0838: catch(IOException e) {
0839: throw new OperationsException("deserialize error: " + e.toString());
0840: }
0841: return objectLoader;
0842: }
0843:
0844: public ObjectInputStream deserialize(String className, ObjectName loaderName, byte bytes[]) throws InstanceNotFoundException, OperationsException, ReflectionException {
0845: if(className == null || className.trim().length() == 0) {throw new RuntimeOperationsException(new IllegalArgumentException("Invalid class name"));}
0846: if(bytes == null || bytes.length == 0)
0847: throw new RuntimeOperationsException(new IllegalArgumentException(), "byte array parameter cannot be null or empty");
0848: if(loaderName == null) return deserialize(className,bytes);
0849: else return deserialize(loaderName, bytes);
0850: }
0851: */
0852:
0853: // ================= jmx 1.2
0854: /**
0855: * <p>Return the {@link java.lang.ClassLoader} that was used for
0856: * loading the class of the named MBean.</p>
0857: *
0858: * @param objectName The ObjectName of the MBean.
0859: *
0860: * @return The ClassLoader used for that MBean. If <var>l</var>
0861: * is the MBean's actual ClassLoader, and <var>r</var> is the
0862: * returned value, then either:
0863: *
0864: * <ul>
0865: * <li><var>r</var> is identical to <var>l</var>; or
0866: * <li>the result of <var>r</var>{@link
0867: * ClassLoader#loadClass(String) .loadClass(<var>s</var>)} is the
0868: * same as <var>l</var>{@link ClassLoader#loadClass(String)
0869: * .loadClass(<var>s</var>)} for any string <var>s</var>.
0870: * </ul>
0871: *
0872: * What this means is that the ClassLoader may be wrapped in
0873: * another ClassLoader for security or other reasons.
0874: *
0875: * @exception InstanceNotFoundException if the named MBean is not found.
0876: * @since JMX 1.2
0877: */
0878: public ClassLoader getClassLoaderFor(ObjectName objectName)
0879: throws InstanceNotFoundException {
0880: if (objectName == null)
0881: throw new RuntimeOperationsException(
0882: new IllegalArgumentException(
0883: "Object name cannot be null"));
0884: if (!repoctrl.contains(objectName))
0885: throw new InstanceNotFoundException(objectName.toString());
0886: MBeanMetaData meta = repoctrl.retrieve(objectName);
0887: PermissionChecker.checkMBeanPermission(meta.getClassName(),
0888: null, objectName, MBeanPermission.GetClassLoaderFor);
0889: sendInterceptorNotification(
0890: ExtendedMBeanServerNotification.GET_CLASSLOADERFOR_NOTIFICATION,
0891: objectName,
0892: ExtendedMBeanServerNotification.GET_CLASSLOADER_FOR,
0893: null);
0894: return meta.getClassLoader();
0895:
0896: }
0897:
0898: /**
0899: * <p>Return the named {@link java.lang.ClassLoader}.</p>
0900: *
0901: * @param loaderName The ObjectName of the ClassLoader. May be
0902: * null, in which case the MBean server's own ClassLoader is
0903: * returned.
0904: *
0905: * @return The named ClassLoader. If <var>l</var> is the actual
0906: * ClassLoader with that name, and <var>r</var> is the returned
0907: * value, then either:
0908: *
0909: * <ul>
0910: * <li><var>r</var> is identical to <var>l</var>; or
0911: * <li>the result of <var>r</var>{@link
0912: * ClassLoader#loadClass(String) .loadClass(<var>s</var>)} is the
0913: * same as <var>l</var>{@link ClassLoader#loadClass(String)
0914: * .loadClass(<var>s</var>)} for any string <var>s</var>.
0915: * </ul>
0916: *
0917: * What this means is that the ClassLoader may be wrapped in
0918: * another ClassLoader for security or other reasons.
0919: *
0920: * @exception InstanceNotFoundException if the named ClassLoader is
0921: * not found.
0922: * @since JMX 1.2
0923: */
0924: public ClassLoader getClassLoader(ObjectName loaderName)
0925: throws InstanceNotFoundException {
0926: if (loaderName == null) {
0927: PermissionChecker.checkMBeanPermission(null, null, null,
0928: MBeanPermission.GetClassLoader);
0929: return this .getClass().getClassLoader();
0930: } else {
0931: if (!repoctrl.contains(loaderName))
0932: throw new InstanceNotFoundException(loaderName
0933: .toString());
0934: MBeanMetaData meta = repoctrl.retrieve(loaderName);
0935: PermissionChecker.checkMBeanPermission(meta.getClassName(),
0936: null, loaderName, MBeanPermission.GetClassLoader);
0937: sendInterceptorNotification(
0938: ExtendedMBeanServerNotification.GET_CLASSLOADER_NOTIFICATION,
0939: loaderName,
0940: ExtendedMBeanServerNotification.GET_CLASSLOADER,
0941: null);
0942:
0943: Object obj = meta.getMBeanObject();
0944: /* Check if the given MBean is a ClassLoader */
0945: if (!(obj instanceof ClassLoader)) {
0946: throw new InstanceNotFoundException(loaderName
0947: .toString()
0948: + " is not a classloader");
0949: }
0950:
0951: return (ClassLoader) obj;
0952:
0953: }
0954: }
0955:
0956: public ClassLoaderRepository getClassLoaderRepository() {
0957: return loaderRepo;
0958: }
0959:
0960: public String[] getDomains() {
0961: PermissionChecker.checkMBeanPermission(null, null, null,
0962: MBeanPermission.GetDomains);
0963: String[] domains = repoctrl.getDomains();
0964: // Check if the caller has the right to invoke 'getDomains'
0965: // on each specific domain in the list.
0966: //
0967: if (System.getSecurityManager() == null) {
0968: return domains;
0969: } else {
0970: ArrayList vdomains = new ArrayList(domains.length);
0971: for (int i = 0; i < domains.length; i++) {
0972: try {
0973: ObjectName domain = new ObjectName(domains[i]
0974: + ":x=y");
0975: PermissionChecker.checkMBeanPermission(null, null,
0976: domain, MBeanPermission.GetDomains);
0977: vdomains.add(domains[i]);
0978: } catch (MalformedObjectNameException e) {
0979: // Should never occur...
0980: } catch (SecurityException e) {
0981: // Do not add this domain to the list
0982: }
0983: }
0984:
0985: // Make an array from vdomains.
0986: //
0987: return (String[]) vdomains.toArray(new String[vdomains
0988: .size()]);
0989: }
0990:
0991: }
0992:
0993: /**
0994: * <p>Removes a listener from a registered MBean.</p>
0995: *
0996: * <p>The MBean must have a listener that exactly matches the
0997: * given <code>listener</code>, <code>filter</code>, and
0998: * <code>handback</code> parameters. If there is more than one
0999: * such listener, only one is removed.</p>
1000: *
1001: * <p>The <code>filter</code> and <code>handback</code> parameters
1002: * may be null if and only if they are null in a listener to be
1003: * removed.</p>
1004: *
1005: * @param objectName The name of the MBean on which the listener should
1006: * be removed.
1007: * @param listenerName A listener that was previously added to this
1008: * MBean.
1009: * @param filter The filter that was specified when the listener
1010: * was added.
1011: * @param handback The handback that was specified when the
1012: * listener was added.
1013: *
1014: * @exception InstanceNotFoundException The MBean name provided
1015: * does not match any of the registered MBeans.
1016: * @exception ListenerNotFoundException The listener is not
1017: * registered in the MBean, or it is not registered with the given
1018: * filter and handback.
1019: *
1020: * @see #addNotificationListener(ObjectName, ObjectName,
1021: * NotificationFilter, Object)
1022: *
1023: * @since JMX 1.2
1024: */
1025:
1026: public void removeNotificationListener(ObjectName objectName,
1027: ObjectName listenerName, NotificationFilter filter,
1028: Object handback) throws InstanceNotFoundException,
1029: ListenerNotFoundException {
1030: if (objectName == null)
1031: throw new RuntimeOperationsException(
1032: new IllegalArgumentException(
1033: "Object name cannot be null"));
1034: if (listenerName == null)
1035: throw new RuntimeOperationsException(
1036: new IllegalArgumentException(
1037: "Object name cannot be null"));
1038: if (!repoctrl.contains(objectName))
1039: throw new InstanceNotFoundException(objectName.toString());
1040: if (!repoctrl.contains(listenerName))
1041: throw new InstanceNotFoundException(listenerName.toString());
1042:
1043: Object instance;
1044: try {
1045: instance = repoctrl.retrieve(listenerName).getMBeanObject();
1046: } catch (InstanceNotFoundException e) {
1047: throw new ListenerNotFoundException(e.getMessage());
1048: }
1049:
1050: if (!(instance instanceof NotificationListener)) {
1051: throw new ListenerNotFoundException(listenerName.toString()
1052: + " is not a NotificationListener.");
1053: }
1054: removeNotificationListener(objectName,
1055: (NotificationListener) instance, filter, handback);
1056:
1057: }
1058:
1059: /**
1060: * <p>Removes a listener from a registered MBean.</p>
1061: *
1062: * <p>The MBean must have a listener that exactly matches the
1063: * given <code>listener</code>, <code>filter</code>, and
1064: * <code>handback</code> parameters. If there is more than one
1065: * such listener, only one is removed.</p>
1066: *
1067: * <p>The <code>filter</code> and <code>handback</code> parameters
1068: * may be null if and only if they are null in a listener to be
1069: * removed.</p>
1070: *
1071: * @param objectName The name of the MBean on which the listener should
1072: * be removed.
1073: * @param listener A listener that was previously added to this
1074: * MBean.
1075: * @param filter The filter that was specified when the listener
1076: * was added.
1077: * @param handback The handback that was specified when the
1078: * listener was added.
1079: *
1080: * @exception InstanceNotFoundException The MBean name provided
1081: * does not match any of the registered MBeans.
1082: * @exception ListenerNotFoundException The listener is not
1083: * registered in the MBean, or it is not registered with the given
1084: * filter and handback.
1085: *
1086: * @see #addNotificationListener(ObjectName, NotificationListener,
1087: * NotificationFilter, Object)
1088: *
1089: * @since JMX 1.2
1090: */
1091: public void removeNotificationListener(ObjectName objectName,
1092: NotificationListener listener, NotificationFilter filter,
1093: Object handback) throws InstanceNotFoundException,
1094: ListenerNotFoundException {
1095: if (objectName == null)
1096: throw new RuntimeOperationsException(
1097: new IllegalArgumentException(
1098: "Object name cannot be null"));
1099: if (!repoctrl.contains(objectName))
1100: throw new InstanceNotFoundException(objectName.toString());
1101:
1102: MBeanMetaData meta = repoctrl.retrieve(objectName);
1103: PermissionChecker.checkMBeanPermission(meta.getClassName(),
1104: null, objectName,
1105: MBeanPermission.RemoveNotificationListener);
1106:
1107: sendInterceptorNotification(
1108: ExtendedMBeanServerNotification.REMOVE_NOTIFICATIONLISTENER_NOTIFICATION,
1109: objectName,
1110: ExtendedMBeanServerNotification.REMOVE_NOTIFICATION_LISTENER,
1111: new Object[] { filter, listener, handback });
1112:
1113: Object obj = meta.getMBeanObject();
1114: if (!(obj instanceof NotificationEmitter)) {
1115: throw new RuntimeOperationsException(
1116: new IllegalArgumentException(objectName.toString()),
1117: "ObjectName " + objectName
1118: + " is not a NotificationEmitter.");
1119: }
1120: ((NotificationEmitter) obj).removeNotificationListener(
1121: listener, filter, handback);
1122: }
1123:
1124: /**
1125: * This function is JFoxMX private extension
1126: * @param interceptor
1127: */
1128:
1129: public void registerInterceptor(
1130: MBeanServerInterceptorListener interceptor,
1131: MBeanServerNotificationFilter filter, Object handback) {
1132: delegate.addNotificationListener(interceptor, filter, handback);
1133: }
1134:
1135: public void unregisterInterceptor(
1136: MBeanServerInterceptorListener interceptor)
1137: throws ListenerNotFoundException {
1138: delegate.removeNotificationListener(interceptor);
1139: }
1140:
1141: private void sendInterceptorNotification(String type,
1142: ObjectName objectName, String operationName, Object[] params) {
1143: if (delegate instanceof ExtendedMBeanServerDelegate) {
1144: ((ExtendedMBeanServerDelegate) delegate).sendNotification(
1145: type, objectName, operationName, params);
1146: }
1147: }
1148: }
|