use of javax.management.NotificationListener in project jdk8u_jdk by JetBrains.
the class DefaultMBeanServerInterceptor method addNotificationListener.
/*
* Notification handling.
*
* This is not trivial, because the MBeanServer translates the
* source of a received notification from a reference to an MBean
* into the ObjectName of that MBean. While that does make
* notification sending easier for MBean writers, it comes at a
* considerable cost. We need to replace the source of a
* notification, which is basically wrong if there are also
* listeners registered directly with the MBean (without going
* through the MBean server). We also need to wrap the listener
* supplied by the client of the MBeanServer with a listener that
* performs the substitution before forwarding. This is why we
* strongly discourage people from putting MBean references in the
* source of their notifications. Instead they should arrange to
* put the ObjectName there themselves.
*
* However, existing code relies on the substitution, so we are
* stuck with it.
*
* Here's how we handle it. When you add a listener, we make a
* ListenerWrapper around it. We look that up in the
* listenerWrappers map, and if there was already a wrapper for
* that listener with the given ObjectName, we reuse it. This map
* is a WeakHashMap, so a listener that is no longer registered
* with any MBean can be garbage collected.
*
* We cannot use simpler solutions such as always creating a new
* wrapper or always registering the same listener with the MBean
* and using the handback to find the client's original listener.
* The reason is that we need to support the removeListener
* variant that removes all (listener,filter,handback) triples on
* a broadcaster that have a given listener. And we do not have
* any way to inspect a broadcaster's internal list of triples.
* So the same client listener must always map to the same
* listener registered with the broadcaster.
*
* Another possible solution would be to map from ObjectName to
* list of listener wrappers (or IdentityHashMap of listener
* wrappers), making this list the first time a listener is added
* on a given MBean, and removing it when the MBean is removed.
* This is probably more costly in memory, but could be useful if
* some day we don't want to rely on weak references.
*/
public void addNotificationListener(ObjectName name, NotificationListener listener, NotificationFilter filter, Object handback) throws InstanceNotFoundException {
// ------------------------------
if (MBEANSERVER_LOGGER.isLoggable(Level.FINER)) {
MBEANSERVER_LOGGER.logp(Level.FINER, DefaultMBeanServerInterceptor.class.getName(), "addNotificationListener", "ObjectName = " + name);
}
DynamicMBean instance = getMBean(name);
checkMBeanPermission(instance, null, name, "addNotificationListener");
NotificationBroadcaster broadcaster = getNotificationBroadcaster(name, instance, NotificationBroadcaster.class);
// ------------------
if (listener == null) {
throw new RuntimeOperationsException(new IllegalArgumentException("Null listener"), "Null listener");
}
NotificationListener listenerWrapper = getListenerWrapper(listener, name, instance, true);
broadcaster.addNotificationListener(listenerWrapper, filter, handback);
}
use of javax.management.NotificationListener in project jdk8u_jdk by JetBrains.
the class DefaultMBeanServerInterceptor method removeNotificationListener.
public void removeNotificationListener(ObjectName name, ObjectName listener) throws InstanceNotFoundException, ListenerNotFoundException {
NotificationListener instance = getListener(listener);
if (MBEANSERVER_LOGGER.isLoggable(Level.FINER)) {
MBEANSERVER_LOGGER.logp(Level.FINER, DefaultMBeanServerInterceptor.class.getName(), "removeNotificationListener", "ObjectName = " + name + ", Listener = " + listener);
}
server.removeNotificationListener(name, instance);
}
use of javax.management.NotificationListener in project jdk8u_jdk by JetBrains.
the class DefaultMBeanServerInterceptor method getListener.
private NotificationListener getListener(ObjectName listener) throws ListenerNotFoundException {
// ----------------
// Get listener object
// ----------------
DynamicMBean instance;
try {
instance = getMBean(listener);
} catch (InstanceNotFoundException e) {
throw EnvHelp.initCause(new ListenerNotFoundException(e.getMessage()), e);
}
Object resource = getResource(instance);
if (!(resource instanceof NotificationListener)) {
final RuntimeException exc = new IllegalArgumentException(listener.getCanonicalName());
final String msg = "MBean " + listener.getCanonicalName() + " does not " + "implement " + NotificationListener.class.getName();
throw new RuntimeOperationsException(exc, msg);
}
return (NotificationListener) resource;
}
use of javax.management.NotificationListener in project jdk8u_jdk by JetBrains.
the class DefaultMBeanServerInterceptor method addNotificationListener.
public void addNotificationListener(ObjectName name, ObjectName listener, NotificationFilter filter, Object handback) throws InstanceNotFoundException {
// ------------------------------
// ------------------------------
// ----------------
// Get listener object
// ----------------
DynamicMBean instance = getMBean(listener);
Object resource = getResource(instance);
if (!(resource instanceof NotificationListener)) {
throw new RuntimeOperationsException(new IllegalArgumentException(listener.getCanonicalName()), "The MBean " + listener.getCanonicalName() + "does not implement the NotificationListener interface");
}
// ----------------
if (MBEANSERVER_LOGGER.isLoggable(Level.FINER)) {
MBEANSERVER_LOGGER.logp(Level.FINER, DefaultMBeanServerInterceptor.class.getName(), "addNotificationListener", "ObjectName = " + name + ", Listener = " + listener);
}
server.addNotificationListener(name, (NotificationListener) resource, filter, handback);
}
use of javax.management.NotificationListener in project jdk8u_jdk by JetBrains.
the class DefaultMBeanServerInterceptor method getListenerWrapper.
/*
* 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, DynamicMBean mbean, boolean create) {
Object resource = getResource(mbean);
ListenerWrapper wrapper = new ListenerWrapper(l, name, resource);
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;
}
}
Aggregations