📄 defaultmbeanserverinterceptor.java
字号:
if (loaderName == null) { checkMBeanPermission((String) null, null, null, "getClassLoader"); return server.getClass().getClassLoader(); } DynamicMBean instance = getMBean(loaderName); checkMBeanPermission(instance, null, loaderName, "getClassLoader"); Object resource = getResource(instance); /* Check if the given MBean is a ClassLoader */ if (!(resource instanceof ClassLoader)) throw new InstanceNotFoundException(loaderName.toString() + " is not a classloader"); return (ClassLoader) resource; } /** * Adds a MBean in the repository */ private void internal_addObject(DynamicMBean object, ObjectName logicalName) throws InstanceAlreadyExistsException { // ------------------------------ // ------------------------------ // Let the repository do the work. try { synchronized(this) { repository.addMBean(object, logicalName); } } catch (InstanceAlreadyExistsException e) { if (object instanceof MBeanRegistration) { postRegisterInvoke((MBeanRegistration) object, false, true); } throw e; } // --------------------- // Send create event // --------------------- if (isTraceOn()) { trace("addObject", "Send create notification of object " + logicalName.getCanonicalName()); } sendNotification(MBeanServerNotification.REGISTRATION_NOTIFICATION, logicalName ) ; } /** * Sends an MBeanServerNotifications with the specified type for the * MBean with the specified ObjectName */ private void sendNotification(String NotifType, ObjectName name) { // ------------------------------ // ------------------------------ // --------------------- // Create notification // --------------------- MBeanServerNotification notif = new MBeanServerNotification( NotifType,MBeanServerDelegate.DELEGATE_NAME,0,name); if (isTraceOn()) { trace("sendNotification", NotifType + " " + name); } delegate.sendNotification(notif); } /** * Applies the specified queries to the set of NamedObjects. */ private Set<ObjectName> objectNamesFromFilteredNamedObjects(Set<NamedObject> list, QueryExp query) { Set<ObjectName> result = new HashSet<ObjectName>(); // No query ... if (query == null) { for (NamedObject no : list) { result.add(no.getName()); } } else { // Access the filter MBeanServer oldServer = QueryEval.getMBeanServer(); query.setMBeanServer(server); try { for (NamedObject no : list) { final DynamicMBean obj = no.getObject(); boolean res; try { res = query.apply(no.getName()); } catch (Exception e) { res = false; } if (res) { result.add(no.getName()); } } } finally { /* * query.setMBeanServer is probably * QueryEval.setMBeanServer so put back the old * value. Since that method uses a ThreadLocal * variable, this code is only needed for the * unusual case where the user creates a custom * QueryExp that calls a nested query on another * MBeanServer. */ query.setMBeanServer(oldServer); } } return result; } /** * Applies the specified queries to the set of NamedObjects. */ private Set<ObjectInstance> objectInstancesFromFilteredNamedObjects(Set<NamedObject> list, QueryExp query) { Set<ObjectInstance> result = new HashSet<ObjectInstance>(); // No query ... if (query == null) { for (NamedObject no : list) { final DynamicMBean obj = no.getObject(); final String className = safeGetClassName(obj); result.add(new ObjectInstance(no.getName(), className)); } } else { // Access the filter MBeanServer oldServer = QueryEval.getMBeanServer(); query.setMBeanServer(server); try { for (NamedObject no : list) { final DynamicMBean obj = no.getObject(); boolean res; try { res = query.apply(no.getName()); } catch (Exception e) { res = false; } if (res) { String className = safeGetClassName(obj); result.add(new ObjectInstance(no.getName(), className)); } } } finally { /* * query.setMBeanServer is probably * QueryEval.setMBeanServer so put back the old * value. Since that method uses a ThreadLocal * variable, this code is only needed for the * unusual case where the user creates a custom * QueryExp that calls a nested query on another * MBeanServer. */ query.setMBeanServer(oldServer); } } return result; } private static String safeGetClassName(DynamicMBean mbean) { try { return getClassName(mbean); } catch (Exception e) { debugX("Exception getting MBean class name", e); return null; } } /** * Applies the specified queries to the set of ObjectInstances. */ private Set<ObjectInstance> filterListOfObjectInstances(Set<ObjectInstance> list, QueryExp query) { // Null query. // if (query == null) { return list; } else { Set<ObjectInstance> result = new HashSet<ObjectInstance>(); // Access the filter. // for (ObjectInstance oi : list) { boolean res = false; MBeanServer oldServer = QueryEval.getMBeanServer(); query.setMBeanServer(server); try { res = query.apply(oi.getObjectName()); } catch (Exception e) { res = false; } finally { /* * query.setMBeanServer is probably * QueryEval.setMBeanServer so put back the old * value. Since that method uses a ThreadLocal * variable, this code is only needed for the * unusual case where the user creates a custom * QueryExp that calls a nested query on another * MBeanServer. */ query.setMBeanServer(oldServer); } if (res) { result.add(oi); } } return result; } } /* * Get the existing wrapper for this listener, name, and mbean, if * there is one. Otherwise, if "create" is true, create and * return one. Otherwise, return null. * * We use a WeakHashMap so that if the only reference to a user * listener is in listenerWrappers, it can be garbage collected. * This requires a certain amount of care, because only the key in * a WeakHashMap is weak; the value is strong. We need to recover * the existing wrapper object (not just an object that is equal * to it), so we would like listenerWrappers to map any * ListenerWrapper to the canonical ListenerWrapper for that * (listener,name,mbean) set. But we do not want this canonical * wrapper to be referenced strongly. Therefore we put it inside * a WeakReference and that is the value in the WeakHashMap. */ private NotificationListener getListenerWrapper(NotificationListener l, ObjectName name, Object mbean, boolean create) { ListenerWrapper wrapper = new ListenerWrapper(l, name, mbean); synchronized (listenerWrappers) { WeakReference<ListenerWrapper> ref = listenerWrappers.get(wrapper); if (ref != null) { NotificationListener existing = ref.get(); if (existing != null) return existing; } if (create) { ref = new WeakReference<ListenerWrapper>(wrapper); listenerWrappers.put(wrapper, ref); return wrapper; } else return null; } } private static class ListenerWrapper implements NotificationListener { ListenerWrapper(NotificationListener l, ObjectName name, Object mbean) { this.listener = l; this.name = name; this.mbean = mbean; } public void handleNotification(Notification notification, Object handback) { if (notification != null) { if (notification.getSource() == mbean) notification.setSource(name); } /* * Listeners are not supposed to throw exceptions. If * this one does, we could remove it from the MBean. It * might indicate that a connector has stopped working, * for instance, and there is no point in sending future * notifications over that connection. However, this * seems rather drastic, so instead we propagate the * exception and let the broadcaster handle it. */ listener.handleNotification(notification, handback); } public boolean equals(Object o) { if (!(o instanceof ListenerWrapper)) return false; ListenerWrapper w = (ListenerWrapper) o; return (w.listener == listener && w.mbean == mbean && w.name.equals(name)); /* * We compare all three, in case the same MBean object * gets unregistered and then reregistered under a * different name, or the same name gets assigned to two * different MBean objects at different times. We do the * comparisons in this order to avoid the slow * ObjectName.equals when possible. */ } public int hashCode() { return (System.identityHashCode(listener) ^ System.identityHashCode(mbean)); /* * We do not include name.hashCode() in the hash because * computing it is slow and usually we will not have two * instances of ListenerWrapper with the same mbean but * different ObjectNames. That can happen if the MBean is * unregistered from one name and reregistered with * another, and there is no garbage collection between; or * if the same object is registered under two names (which * is not recommended because MBeanRegistration will * break). But even in these unusual cases the hash code * does not have to be unique. */ } private NotificationListener listener; private ObjectName name; private Object mbean; } // SECURITY CHECKS //---------------- private static String getClassName(DynamicMBean mbean) { if (mbean instanceof DynamicMBean2) return ((DynamicMBean2) mbean).getClassName(); else return mbean.getMBeanInfo().getClassName(); } private static void checkMBeanPermission(DynamicMBean mbean, String member, ObjectName objectName, String actions) { SecurityManager sm = System.getSecurityManager(); if (sm != null) { checkMBeanPermission(safeGetClassName(mbean), member, objectName, actions); } } private static void checkMBeanPermission(String classname, String member, ObjectName objectName, String actions) { SecurityManager sm = System.getSecurityManager(); if (sm != null) { Permission perm = new MBeanPermission(classname, member, objectName, actions); sm.checkPermission(perm); } } private static void checkMBeanTrustPermission(final Class theClass) throws SecurityException { SecurityManager sm = System.getSecurit
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -