use of javax.management.RuntimeOperationsException in project geode by apache.
the class MX4JModelMBean method removeAttributeChangeNotificationListener.
// Not in the spec but needed
private void removeAttributeChangeNotificationListener(NotificationListener listener, String attributeName, Object handback) throws MBeanException, RuntimeOperationsException, ListenerNotFoundException {
if (listener == null)
throw new RuntimeOperationsException(new IllegalArgumentException(LocalizedStrings.MX4JModelMBean_LISTENER_CANNOT_BE_NULL.toLocalizedString()));
AttributeChangeNotificationFilter filter = new AttributeChangeNotificationFilter();
if (attributeName != null) {
filter.enableAttribute(attributeName);
} else {
MBeanAttributeInfo[] ai = m_modelMBeanInfo.getAttributes();
for (int i = 0; i < ai.length; i++) {
Descriptor d = ((ModelMBeanAttributeInfo) ai[i]).getDescriptor();
filter.enableAttribute((String) d.getFieldValue("name"));
}
}
getAttributeChangeBroadcaster().removeNotificationListener(listener, filter, handback);
Logger logger = getLogger();
if (logger.isEnabledFor(Logger.DEBUG))
logger.debug("Listener " + listener + " for attribute " + attributeName + " removed successfully, handback is " + handback);
}
use of javax.management.RuntimeOperationsException in project geode by apache.
the class MX4JModelMBean method setAttribute.
public void setAttribute(Attribute attribute) throws AttributeNotFoundException, InvalidAttributeValueException, MBeanException, ReflectionException {
if (attribute == null)
throw new RuntimeOperationsException(new IllegalArgumentException(LocalizedStrings.MX4JModelMBean_ATTRIBUTE_CANNOT_BE_NULL.toLocalizedString()));
Logger logger = getLogger();
// No need to synchronize: I work mostly on clones
// I want the real info, not its clone
ModelMBeanInfo info = getModelMBeanInfo();
if (info == null)
throw new AttributeNotFoundException(LocalizedStrings.MX4JModelMBean_MODELMBEANINFO_IS_NULL.toLocalizedString());
if (logger.isEnabledFor(Logger.DEBUG))
logger.debug("ModelMBeanInfo is: " + info);
String attrName = attribute.getName();
Object attrValue = attribute.getValue();
// This is a clone, we use it read only
ModelMBeanAttributeInfo attrInfo = info.getAttribute(attrName);
if (attrInfo == null)
throw new AttributeNotFoundException(LocalizedStrings.MX4JModelMBean_CANNOT_FIND_MODELMBEANATTRIBUTEINFO_FOR_ATTRIBUTE_0.toLocalizedString(attrName));
if (logger.isEnabledFor(Logger.DEBUG))
logger.debug("Attribute info is: " + attrInfo);
if (!attrInfo.isWritable())
throw new AttributeNotFoundException(LocalizedStrings.MX4JModelMBean_ATTRIBUTE_0_IS_NOT_WRITABLE.toLocalizedString(attrName));
// This returns a clone of the mbean descriptor, we use it read only
Descriptor mbeanDescriptor = info.getMBeanDescriptor();
if (mbeanDescriptor == null)
throw new AttributeNotFoundException(LocalizedStrings.MX4JModelMBean_MBEAN_DESCRIPTOR_CANNOT_BE_NULL.toLocalizedString());
if (logger.isEnabledFor(Logger.DEBUG))
logger.debug("MBean descriptor is: " + mbeanDescriptor);
// This descriptor is a clone
Descriptor attributeDescriptor = attrInfo.getDescriptor();
if (attributeDescriptor == null)
throw new AttributeNotFoundException(LocalizedStrings.MX4JModelMBean_ATTRIBUTE_DESCRIPTOR_FOR_ATTRIBUTE_0_CANNOT_BE_NULL.toLocalizedString(attrName));
if (logger.isEnabledFor(Logger.DEBUG))
logger.debug("Attribute descriptor is: " + attributeDescriptor);
String lastUpdateField = "lastUpdatedTimeStamp";
Object oldValue = null;
try {
oldValue = getAttribute(attrName);
if (logger.isEnabledFor(Logger.DEBUG))
logger.debug("Previous value of attribute " + attrName + ": " + oldValue);
} catch (Exception x) {
if (logger.isEnabledFor(Logger.DEBUG))
logger.debug("Cannot get previous value of attribute " + attrName, x);
}
// Check if setMethod is present
String method = (String) attributeDescriptor.getFieldValue("setMethod");
if (logger.isEnabledFor(Logger.DEBUG))
logger.debug("setMethod field is: " + method);
if (method != null) {
Class declared = loadClassWithContextClassLoader(attrInfo.getType());
if (attrValue != null) {
Class parameter = attrValue.getClass();
checkAssignability(parameter, declared);
}
// As an extension, allow attributes to be called on target objects also
Object target = resolveTargetObject(attributeDescriptor);
invokeMethod(target, method, new Class[] { declared }, new Object[] { attrValue });
// Cache the value only if currencyTimeLimit is not 0, ie it is not always stale
int staleness = getStaleness(attributeDescriptor, mbeanDescriptor, lastUpdateField);
if (staleness != ALWAYS_STALE) {
attributeDescriptor.setField("value", attrValue);
attributeDescriptor.setField(lastUpdateField, Long.valueOf(System.currentTimeMillis()));
if (logger.isEnabledFor(Logger.TRACE))
logger.trace("Attribute's value has been cached");
} else {
if (logger.isEnabledFor(Logger.TRACE))
logger.trace("Always stale, avoiding to cache attribute's value");
}
} else {
if (attrValue != null) {
Class parameter = attrValue.getClass();
Class declared = loadClassWithContextClassLoader(attrInfo.getType());
checkAssignability(parameter, declared);
}
// Always store the value in the descriptor: no setMethod
attributeDescriptor.setField("value", attrValue);
}
// And now replace the descriptor with the updated clone
info.setDescriptor(attributeDescriptor, "attribute");
// Send notifications to listeners
if (logger.isEnabledFor(Logger.TRACE))
logger.trace("Sending attribute change notifications");
sendAttributeChangeNotification(new Attribute(attrName, oldValue), attribute);
// Persist this ModelMBean
boolean persistNow = shouldPersistNow(attributeDescriptor, mbeanDescriptor, lastUpdateField);
if (persistNow) {
if (logger.isEnabledFor(Logger.TRACE))
logger.trace("Persisting this ModelMBean...");
try {
store();
if (logger.isEnabledFor(Logger.TRACE))
logger.trace("ModelMBean persisted successfully");
} catch (Exception x) {
logger.error(LocalizedStrings.MX4JModelMBean_CANNOT_STORE_MODELMBEAN_AFTER_SETATTRIBUTE, x);
if (x instanceof MBeanException)
throw (MBeanException) x;
else
throw new MBeanException(x);
}
}
}
use of javax.management.RuntimeOperationsException 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.RuntimeOperationsException in project jdk8u_jdk by JetBrains.
the class DefaultMBeanServerInterceptor method registerDynamicMBean.
private ObjectInstance registerDynamicMBean(String classname, DynamicMBean mbean, ObjectName name) throws InstanceAlreadyExistsException, MBeanRegistrationException, NotCompliantMBeanException {
name = nonDefaultDomain(name);
if (MBEANSERVER_LOGGER.isLoggable(Level.FINER)) {
MBEANSERVER_LOGGER.logp(Level.FINER, DefaultMBeanServerInterceptor.class.getName(), "registerMBean", "ObjectName = " + name);
}
ObjectName logicalName = preRegister(mbean, server, name);
// preRegister returned successfully, so from this point on we
// must call postRegister(false) if there is any problem.
boolean registered = false;
boolean registerFailed = false;
ResourceContext context = null;
try {
if (mbean instanceof DynamicMBean2) {
try {
((DynamicMBean2) mbean).preRegister2(server, logicalName);
// until we succeed
registerFailed = true;
} catch (Exception e) {
if (e instanceof RuntimeException)
throw (RuntimeException) e;
if (e instanceof InstanceAlreadyExistsException)
throw (InstanceAlreadyExistsException) e;
throw new RuntimeException(e);
}
}
if (logicalName != name && logicalName != null) {
logicalName = ObjectName.getInstance(nonDefaultDomain(logicalName));
}
checkMBeanPermission(classname, null, logicalName, "registerMBean");
if (logicalName == null) {
final RuntimeException wrapped = new IllegalArgumentException("No object name specified");
throw new RuntimeOperationsException(wrapped, "Exception occurred trying to register the MBean");
}
final Object resource = getResource(mbean);
// Register the MBean with the repository.
// Returns the resource context that was used.
// The returned context does nothing for regular MBeans.
// For ClassLoader MBeans the context makes it possible to register these
// objects with the appropriate framework artifacts, such as
// the CLR, from within the repository lock.
// In case of success, we also need to call context.done() at the
// end of this method.
//
context = registerWithRepository(resource, mbean, logicalName);
registerFailed = false;
registered = true;
} finally {
try {
postRegister(logicalName, mbean, registered, registerFailed);
} finally {
if (registered && context != null)
context.done();
}
}
return new ObjectInstance(logicalName, classname);
}
use of javax.management.RuntimeOperationsException in project jdk8u_jdk by JetBrains.
the class DefaultMBeanServerInterceptor method getNotificationBroadcaster.
private static <T extends NotificationBroadcaster> T getNotificationBroadcaster(ObjectName name, Object instance, Class<T> reqClass) {
if (reqClass.isInstance(instance))
return reqClass.cast(instance);
if (instance instanceof DynamicMBean2)
instance = ((DynamicMBean2) instance).getResource();
if (reqClass.isInstance(instance))
return reqClass.cast(instance);
final RuntimeException exc = new IllegalArgumentException(name.getCanonicalName());
final String msg = "MBean " + name.getCanonicalName() + " does not " + "implement " + reqClass.getName();
throw new RuntimeOperationsException(exc, msg);
}
Aggregations