use of javax.management.RuntimeOperationsException in project jdk8u_jdk by JetBrains.
the class AddAttributeChangeNotificationListenerTest method run.
private void run(String[] args) throws Exception {
int errCount = 0;
String testName = "AddAttributeChangeNotificationListenerTest0001";
ObjectName modelMBeanObjectName = null;
ModelMBeanInfo modelMBeanInfo = null;
MBeanServer mbeanserver = MBeanServerFactory.newMBeanServer();
String modelMBeanName = "RequiredModelMBean";
String modelMBeanClassName = "javax.management.modelmbean.RequiredModelMBean";
modelMBeanObjectName = new ObjectName("AddAttributeChangeNotificationListenerTest:type=" + modelMBeanName);
System.out.println("Build a ModelMBeanInfo without attribute State");
modelMBeanInfo = createModelMBeanInfo();
System.out.println("Create and register a RequiredModelMBean " + "with that MBeanInfo");
Object[] params = { modelMBeanInfo };
String[] sig = { "javax.management.modelmbean.ModelMBeanInfo" };
mbeanserver.createMBean(modelMBeanClassName, modelMBeanObjectName, params, sig);
ModelMBeanListener aListener = new ModelMBeanListener();
// add an attribute change listener
System.out.println("Add an attribute change listener for State");
try {
mbeanserver.invoke(modelMBeanObjectName, "addAttributeChangeNotificationListener", (new Object[] { aListener, "State", null }), (new String[] { "javax.management.NotificationListener", "java.lang.String", "java.lang.Object" }));
System.out.println("NOK: Did not get expected " + "RuntimeOperationsException");
errCount++;
} catch (Exception e) {
if (e instanceof MBeanException)
e = ((MBeanException) e).getTargetException();
if (e instanceof RuntimeOperationsException) {
RuntimeOperationsException roe = (RuntimeOperationsException) e;
Exception target = roe.getTargetException();
System.out.println("OK: Got expected RuntimeOperationsException");
if (target instanceof IllegalArgumentException) {
System.out.println("OK: Got expected " + "wrapped IllegalArgumentException");
} else {
System.out.println("NOK: Got wrapped " + target + " as we expect IllegalArgumentException");
errCount++;
}
} else {
System.out.println("NOK: Got " + e + " as we expect RuntimeOperationsException");
errCount++;
}
}
if (errCount != 0)
throw new Exception(errCount + " error(s) occured");
}
use of javax.management.RuntimeOperationsException in project jdk8u_jdk by JetBrains.
the class RequiredModelMBean method setAttribute.
/**
* Sets the value of a specific attribute of a named ModelMBean.
*
* If the 'setMethod' field of the attribute's descriptor
* contains the name of a valid operation descriptor, then the
* method described by the operation descriptor is executed.
* In this implementation, the operation descriptor must be specified
* correctly and assigned to the modelMBeanInfo so that the 'setMethod'
* works correctly.
* The response from the method is set as the value of the attribute
* in the descriptor.
*
* <p>If currencyTimeLimit is > 0, then the new value for the
* attribute is cached in the attribute descriptor's
* 'value' field and the 'lastUpdatedTimeStamp' field is set to
* the current time stamp.
*
* <p>If the persist field of the attribute's descriptor is not null
* then Persistence policy from the attribute descriptor is used to
* guide storing the attribute in a persistent store.
* <br>Store the MBean if 'persistPolicy' field is:
* <UL>
* <Li> != "never"</Li>
* <Li> = "always"</Li>
* <Li> = "onUpdate"</Li>
* <Li> {@literal = "onTimer" and now > 'lastPersistTime' + 'persistPeriod'}</Li>
* <Li> {@literal = "NoMoreOftenThan" and now > 'lastPersistTime' +
* 'persistPeriod'}</Li>
* </UL>
* Do not store the MBean if 'persistPolicy' field is:
* <UL>
* <Li> = "never"</Li>
* <Li> = {@literal = "onTimer" && now < 'lastPersistTime' + 'persistPeriod'}</Li>
* <Li> = "onUnregister"</Li>
* <Li> = {@literal = "NoMoreOftenThan" and now < 'lastPersistTime' +
* 'persistPeriod'}</Li>
* </UL>
*
* <p>The ModelMBeanInfo of the Model MBean is stored in a file.
*
* @param attribute The Attribute instance containing the name of
* the attribute to be set and the value it is to be set to.
*
*
* @exception AttributeNotFoundException The specified attribute is
* not accessible in the MBean.
* <br>The following cases may result in an AttributeNotFoundException:
* <UL>
* <LI> No ModelMBeanAttributeInfo is found for the specified
* attribute.</LI>
* <LI> The ModelMBeanAttributeInfo's isWritable method returns
* 'false'.</LI>
* </UL>
* @exception InvalidAttributeValueException No descriptor is defined
* for the specified attribute.
* @exception MBeanException Wraps one of the following Exceptions:
* <UL>
* <LI> An Exception thrown by the managed object's setter.</LI>
* <LI> A {@link ServiceNotFoundException} if a setMethod field is
* defined in the descriptor for the attribute and the managed
* resource is null; or if no setMethod field is defined and
* caching is not enabled for the attribute.
* Note that if there is no getMethod field either, then caching
* is automatically enabled.</LI>
* <LI> {@link InvalidTargetObjectTypeException} The 'targetType'
* field value is not 'objectReference'.</LI>
* <LI> An Exception thrown by the managed object's getter.</LI>
* </UL>
* @exception ReflectionException Wraps an {@link java.lang.Exception}
* thrown while trying to invoke the setter.
* @exception RuntimeOperationsException Wraps an
* {@link IllegalArgumentException}: The attribute in parameter is
* null.
*
* @see #getAttribute(java.lang.String)
**/
public void setAttribute(Attribute attribute) throws AttributeNotFoundException, InvalidAttributeValueException, MBeanException, ReflectionException {
final boolean tracing = MODELMBEAN_LOGGER.isLoggable(Level.FINER);
if (tracing) {
MODELMBEAN_LOGGER.logp(Level.FINER, RequiredModelMBean.class.getName(), "setAttribute()", "Entry");
}
if (attribute == null)
throw new RuntimeOperationsException(new IllegalArgumentException("attribute must not be null"), "Exception occurred trying to set an attribute of a " + "RequiredModelMBean");
/* run setMethod if there is one */
/* return cached value if its current */
/* set cached value in descriptor and set date/time */
/* send attribute change Notification */
/* check persistence policy and persist if need be */
String attrName = attribute.getName();
Object attrValue = attribute.getValue();
boolean updateDescriptor = false;
ModelMBeanAttributeInfo attrInfo = modelMBeanInfo.getAttribute(attrName);
if (attrInfo == null)
throw new AttributeNotFoundException("setAttribute failed: " + attrName + " is not found ");
Descriptor mmbDesc = modelMBeanInfo.getMBeanDescriptor();
Descriptor attrDescr = attrInfo.getDescriptor();
if (attrDescr != null) {
if (!attrInfo.isWritable())
throw new AttributeNotFoundException("setAttribute failed: " + attrName + " is not writable ");
String attrSetMethod = (String) (attrDescr.getFieldValue("setMethod"));
String attrGetMethod = (String) (attrDescr.getFieldValue("getMethod"));
String attrType = attrInfo.getType();
Object currValue = "Unknown";
try {
currValue = this.getAttribute(attrName);
} catch (Throwable t) {
// OK: Default "Unknown" value used for unknown attribute
}
Attribute oldAttr = new Attribute(attrName, currValue);
/* run method from operations descriptor */
if (attrSetMethod == null) {
if (attrValue != null) {
try {
final Class<?> clazz = loadClass(attrType);
if (!clazz.isInstance(attrValue))
throw new InvalidAttributeValueException(clazz.getName() + " expected, " + attrValue.getClass().getName() + " received.");
} catch (ClassNotFoundException x) {
if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
MODELMBEAN_LOGGER.logp(Level.FINER, RequiredModelMBean.class.getName(), "setAttribute(Attribute)", "Class " + attrType + " for attribute " + attrName + " not found: ", x);
}
}
}
updateDescriptor = true;
} else {
invoke(attrSetMethod, (new Object[] { attrValue }), (new String[] { attrType }));
}
/* change cached value */
Object objctl = attrDescr.getFieldValue("currencyTimeLimit");
String ctl;
if (objctl != null)
ctl = objctl.toString();
else
ctl = null;
if ((ctl == null) && (mmbDesc != null)) {
objctl = mmbDesc.getFieldValue("currencyTimeLimit");
if (objctl != null)
ctl = objctl.toString();
else
ctl = null;
}
final boolean updateCache = ((ctl != null) && !(ctl.equals("-1")));
if (attrSetMethod == null && !updateCache && attrGetMethod != null)
throw new MBeanException(new ServiceNotFoundException("No " + "setMethod field is defined in the descriptor for " + attrName + " attribute and caching is not enabled " + "for it"));
if (updateCache || updateDescriptor) {
if (tracing) {
MODELMBEAN_LOGGER.logp(Level.FINER, RequiredModelMBean.class.getName(), "setAttribute(Attribute)", "setting cached value of " + attrName + " to " + attrValue);
}
attrDescr.setField("value", attrValue);
if (updateCache) {
final String currtime = String.valueOf((new Date()).getTime());
attrDescr.setField("lastUpdatedTimeStamp", currtime);
}
attrInfo.setDescriptor(attrDescr);
modelMBeanInfo.setDescriptor(attrDescr, "attribute");
if (tracing) {
final StringBuilder strb = new StringBuilder().append("new descriptor is ").append(attrDescr).append(". AttributeInfo descriptor is ").append(attrInfo.getDescriptor()).append(". AttributeInfo descriptor is ").append(modelMBeanInfo.getDescriptor(attrName, "attribute"));
MODELMBEAN_LOGGER.logp(Level.FINER, RequiredModelMBean.class.getName(), "setAttribute(Attribute)", strb.toString());
}
}
if (tracing) {
MODELMBEAN_LOGGER.logp(Level.FINER, RequiredModelMBean.class.getName(), "setAttribute(Attribute)", "sending sendAttributeNotification");
}
sendAttributeChangeNotification(oldAttr, attribute);
} else {
if (tracing) {
MODELMBEAN_LOGGER.logp(Level.FINER, RequiredModelMBean.class.getName(), "setAttribute(Attribute)", "setMethod failed " + attrName + " not in attributeDescriptor\n");
}
throw new InvalidAttributeValueException("Unable to resolve attribute value, " + "no defined in descriptor for attribute");
}
if (tracing) {
MODELMBEAN_LOGGER.logp(Level.FINER, RequiredModelMBean.class.getName(), "setAttribute(Attribute)", "Exit");
}
}
use of javax.management.RuntimeOperationsException in project jdk8u_jdk by JetBrains.
the class RequiredModelMBean method getAttribute.
/**
* Returns the value of a specific attribute defined for this
* ModelMBean.
* The last value returned by an attribute may be cached in the
* attribute's descriptor.
* The valid value will be in the 'value' field if there is one.
* If the 'currencyTimeLimit' field in the descriptor is:
* <UL>
* <LI> <b><0</b> Then the value is not cached and is never valid.
* The getter method is invoked for the attribute.
* The 'value' and 'lastUpdatedTimeStamp' fields are cleared.</LI>
* <LI> <b>=0</b> Then the value is always cached and always valid.
* The 'value' field is returned. If there is no'value' field
* then the getter method is invoked for the attribute.
* The 'lastUpdatedTimeStamp' field and `value' fields are set
* to the attribute's value and the current time stamp.</LI>
* <LI> <b>>0</b> Represents the number of seconds that the 'value'
* field is valid.
* The 'value' field is no longer valid when
* 'lastUpdatedTimeStamp' + 'currencyTimeLimit' > Now.
* <UL>
* <LI>When 'value' is valid, 'value' is returned.</LI>
* <LI>When 'value' is no longer valid then the getter
* method is invoked for the attribute.
* The 'lastUpdatedTimeStamp' field and `value' fields
* are updated.</LI>
* </UL></LI>
* </UL>
*
* <p><b>Note:</b> because of inconsistencies in previous versions of
* this specification, it is recommended not to use negative or zero
* values for <code>currencyTimeLimit</code>. To indicate that a
* cached value is never valid, omit the
* <code>currencyTimeLimit</code> field. To indicate that it is
* always valid, use a very large number for this field.</p>
*
* <p>If the 'getMethod' field contains the name of a valid
* operation descriptor, then the method described by the
* operation descriptor is executed. The response from the
* method is returned as the value of the attribute. If the
* operation fails or the returned value is not compatible with
* the declared type of the attribute, an exception will be thrown.</p>
*
* <p>If no 'getMethod' field is defined then the default value of the
* attribute is returned. If the returned value is not compatible with
* the declared type of the attribute, an exception will be thrown.</p>
*
* <p>The declared type of the attribute is the String returned by
* {@link ModelMBeanAttributeInfo#getType()}. A value is compatible
* with this type if one of the following is true:
* <ul>
* <li>the value is null;</li>
* <li>the declared name is a primitive type name (such as "int")
* and the value is an instance of the corresponding wrapper
* type (such as java.lang.Integer);</li>
* <li>the name of the value's class is identical to the declared name;</li>
* <li>the declared name can be loaded by the value's class loader and
* produces a class to which the value can be assigned.</li>
* </ul>
*
* <p>In this implementation, in every case where the getMethod needs to
* be called, because the method is invoked through the standard "invoke"
* method and thus needs operationInfo, an operation must be specified
* for that getMethod so that the invocation works correctly.</p>
*
* @param attrName A String specifying the name of the
* attribute to be retrieved. It must match the name of a
* ModelMBeanAttributeInfo.
*
* @return The value of the retrieved attribute from the
* descriptor 'value' field or from the invocation of the
* operation in the 'getMethod' field of the descriptor.
*
* @exception AttributeNotFoundException The specified attribute is
* not accessible in the MBean.
* The following cases may result in an AttributeNotFoundException:
* <UL>
* <LI> No ModelMBeanInfo was found for the Model MBean.</LI>
* <LI> No ModelMBeanAttributeInfo was found for the specified
* attribute name.</LI>
* <LI> The ModelMBeanAttributeInfo isReadable method returns
* 'false'.</LI>
* </UL>
* @exception MBeanException Wraps one of the following Exceptions:
* <UL>
* <LI> {@link InvalidAttributeValueException}: A wrong value type
* was received from the attribute's getter method or
* no 'getMethod' field defined in the descriptor for
* the attribute and no default value exists.</LI>
* <LI> {@link ServiceNotFoundException}: No
* ModelMBeanOperationInfo defined for the attribute's
* getter method or no descriptor associated with the
* ModelMBeanOperationInfo or the managed resource is
* null.</LI>
* <LI> {@link InvalidTargetObjectTypeException} The 'targetType'
* field value is not 'objectReference'.</LI>
* <LI> An Exception thrown by the managed object's getter.</LI>
* </UL>
* @exception ReflectionException Wraps an {@link java.lang.Exception}
* thrown while trying to invoke the getter.
* @exception RuntimeOperationsException Wraps an
* {@link IllegalArgumentException}: The attribute name in
* parameter is null.
*
* @see #setAttribute(javax.management.Attribute)
**/
public Object getAttribute(String attrName) throws AttributeNotFoundException, MBeanException, ReflectionException {
if (attrName == null)
throw new RuntimeOperationsException(new IllegalArgumentException("attributeName must not be null"), "Exception occurred trying to get attribute of a " + "RequiredModelMBean");
final String mth = "getAttribute(String)";
final boolean tracing = MODELMBEAN_LOGGER.isLoggable(Level.FINER);
if (tracing) {
MODELMBEAN_LOGGER.logp(Level.FINER, RequiredModelMBean.class.getName(), mth, "Entry with " + attrName);
}
/* Check attributeDescriptor for getMethod */
Object response;
try {
if (modelMBeanInfo == null)
throw new AttributeNotFoundException("getAttribute failed: ModelMBeanInfo not found for " + attrName);
ModelMBeanAttributeInfo attrInfo = modelMBeanInfo.getAttribute(attrName);
Descriptor mmbDesc = modelMBeanInfo.getMBeanDescriptor();
if (attrInfo == null)
throw new AttributeNotFoundException("getAttribute failed:" + " ModelMBeanAttributeInfo not found for " + attrName);
Descriptor attrDescr = attrInfo.getDescriptor();
if (attrDescr != null) {
if (!attrInfo.isReadable())
throw new AttributeNotFoundException("getAttribute failed: " + attrName + " is not readable ");
response = resolveForCacheValue(attrDescr);
/* return current cached value */
if (tracing) {
MODELMBEAN_LOGGER.logp(Level.FINER, RequiredModelMBean.class.getName(), mth, "*** cached value is " + response);
}
if (response == null) {
/* no cached value, run getMethod */
if (tracing) {
MODELMBEAN_LOGGER.logp(Level.FINER, RequiredModelMBean.class.getName(), mth, "**** cached value is null - getting getMethod");
}
String attrGetMethod = (String) (attrDescr.getFieldValue("getMethod"));
if (attrGetMethod != null) {
/* run method from operations descriptor */
if (tracing) {
MODELMBEAN_LOGGER.logp(Level.FINER, RequiredModelMBean.class.getName(), mth, "invoking a getMethod for " + attrName);
}
Object getResponse = invoke(attrGetMethod, new Object[] {}, new String[] {});
if (getResponse != null) {
// error/validity check return value here
if (tracing) {
MODELMBEAN_LOGGER.logp(Level.FINER, RequiredModelMBean.class.getName(), mth, "got a non-null response " + "from getMethod\n");
}
response = getResponse;
// change cached value in attribute descriptor
Object objctl = attrDescr.getFieldValue("currencyTimeLimit");
String ctl;
if (objctl != null)
ctl = objctl.toString();
else
ctl = null;
if ((ctl == null) && (mmbDesc != null)) {
objctl = mmbDesc.getFieldValue("currencyTimeLimit");
if (objctl != null)
ctl = objctl.toString();
else
ctl = null;
}
if ((ctl != null) && !(ctl.equals("-1"))) {
if (tracing) {
MODELMBEAN_LOGGER.logp(Level.FINER, RequiredModelMBean.class.getName(), mth, "setting cached value and " + "lastUpdatedTime in descriptor");
}
attrDescr.setField("value", response);
final String stamp = String.valueOf((new Date()).getTime());
attrDescr.setField("lastUpdatedTimeStamp", stamp);
attrInfo.setDescriptor(attrDescr);
modelMBeanInfo.setDescriptor(attrDescr, "attribute");
if (tracing) {
MODELMBEAN_LOGGER.logp(Level.FINER, RequiredModelMBean.class.getName(), mth, "new descriptor is " + attrDescr);
MODELMBEAN_LOGGER.logp(Level.FINER, RequiredModelMBean.class.getName(), mth, "AttributeInfo descriptor is " + attrInfo.getDescriptor());
final String attStr = modelMBeanInfo.getDescriptor(attrName, "attribute").toString();
MODELMBEAN_LOGGER.logp(Level.FINER, RequiredModelMBean.class.getName(), mth, "modelMBeanInfo: AttributeInfo " + "descriptor is " + attStr);
}
}
} else {
// response was invalid or really returned null
if (tracing) {
MODELMBEAN_LOGGER.logp(Level.FINER, RequiredModelMBean.class.getName(), mth, "got a null response from getMethod\n");
}
response = null;
}
} else {
// not getMethod so return descriptor (default) value
String qualifier = "";
response = attrDescr.getFieldValue("value");
if (response == null) {
qualifier = "default ";
response = attrDescr.getFieldValue("default");
}
if (tracing) {
MODELMBEAN_LOGGER.logp(Level.FINER, RequiredModelMBean.class.getName(), mth, "could not find getMethod for " + attrName + ", returning descriptor " + qualifier + "value");
}
// !! cast response to right class
}
}
// make sure response class matches type field
final String respType = attrInfo.getType();
if (response != null) {
String responseClass = response.getClass().getName();
if (!respType.equals(responseClass)) {
boolean wrongType = false;
boolean primitiveType = false;
boolean correspondingTypes = false;
for (int i = 0; i < primitiveTypes.length; i++) {
if (respType.equals(primitiveTypes[i])) {
primitiveType = true;
if (responseClass.equals(primitiveWrappers[i]))
correspondingTypes = true;
break;
}
}
if (primitiveType) {
// inequality may come from primitive/wrapper class
if (!correspondingTypes)
wrongType = true;
} else {
// inequality may come from type subclassing
boolean subtype;
try {
final Class respClass = response.getClass();
final Exception[] caughException = new Exception[1];
AccessControlContext stack = AccessController.getContext();
Class c = javaSecurityAccess.doIntersectionPrivilege(new PrivilegedAction<Class<?>>() {
@Override
public Class<?> run() {
try {
ReflectUtil.checkPackageAccess(respType);
ClassLoader cl = respClass.getClassLoader();
return Class.forName(respType, true, cl);
} catch (Exception e) {
caughException[0] = e;
}
return null;
}
}, stack, acc);
if (caughException[0] != null) {
throw caughException[0];
}
subtype = c.isInstance(response);
} catch (Exception e) {
subtype = false;
if (tracing) {
MODELMBEAN_LOGGER.logp(Level.FINER, RequiredModelMBean.class.getName(), mth, "Exception: ", e);
}
}
if (!subtype)
wrongType = true;
}
if (wrongType) {
if (tracing) {
MODELMBEAN_LOGGER.logp(Level.FINER, RequiredModelMBean.class.getName(), mth, "Wrong response type '" + respType + "'");
}
// back right attribute type
throw new MBeanException(new InvalidAttributeValueException("Wrong value type received for get attribute"), "An exception occurred while trying to get an " + "attribute value through a RequiredModelMBean");
}
}
}
} else {
if (tracing) {
MODELMBEAN_LOGGER.logp(Level.FINER, RequiredModelMBean.class.getName(), mth, "getMethod failed " + attrName + " not in attributeDescriptor\n");
}
throw new MBeanException(new InvalidAttributeValueException("Unable to resolve attribute value, " + "no getMethod defined in descriptor for attribute"), "An exception occurred while trying to get an " + "attribute value through a RequiredModelMBean");
}
} catch (MBeanException mbe) {
throw mbe;
} catch (AttributeNotFoundException t) {
throw t;
} catch (Exception e) {
if (tracing) {
MODELMBEAN_LOGGER.logp(Level.FINER, RequiredModelMBean.class.getName(), mth, "getMethod failed with " + e.getMessage() + " exception type " + (e.getClass()).toString());
}
throw new MBeanException(e, "An exception occurred while trying " + "to get an attribute value: " + e.getMessage());
}
if (tracing) {
MODELMBEAN_LOGGER.logp(Level.FINER, RequiredModelMBean.class.getName(), mth, "Exit");
}
return response;
}
use of javax.management.RuntimeOperationsException in project jdk8u_jdk by JetBrains.
the class RequiredModelMBean method setAttributes.
/**
* Sets the values of an array of attributes of this ModelMBean.
* Executes the setAttribute() method for each attribute in the list.
*
* @param attributes A list of attributes: The identification of the
* attributes to be set and the values they are to be set to.
*
* @return The array of attributes that were set, with their new
* values in Attribute instances.
*
* @exception RuntimeOperationsException Wraps an
* {@link IllegalArgumentException}: The object name in parameter
* is null or attributes in parameter is null.
*
* @see #getAttributes
**/
public AttributeList setAttributes(AttributeList attributes) {
if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
MODELMBEAN_LOGGER.logp(Level.FINER, RequiredModelMBean.class.getName(), "setAttribute(Attribute)", "Entry");
}
if (attributes == null)
throw new RuntimeOperationsException(new IllegalArgumentException("attributes must not be null"), "Exception occurred trying to set attributes of a " + "RequiredModelMBean");
final AttributeList responseList = new AttributeList();
// Go through the list of attributes
for (Attribute attr : attributes.asList()) {
try {
setAttribute(attr);
responseList.add(attr);
} catch (Exception excep) {
responseList.remove(attr);
}
}
return responseList;
}
use of javax.management.RuntimeOperationsException in project jdk8u_jdk by JetBrains.
the class RequiredModelMBean method invoke.
/**
* Invokes a method on or through a RequiredModelMBean and returns
* the result of the method execution.
* <P>
* If the given method to be invoked, together with the provided
* signature, matches one of RequiredModelMbean
* accessible methods, this one will be call. Otherwise the call to
* the given method will be tried on the managed resource.
* <P>
* The last value returned by an operation may be cached in
* the operation's descriptor which
* is in the ModelMBeanOperationInfo's descriptor.
* The valid value will be in the 'value' field if there is one.
* If the 'currencyTimeLimit' field in the descriptor is:
* <UL>
* <LI><b><0</b> Then the value is not cached and is never valid.
* The operation method is invoked.
* The 'value' and 'lastUpdatedTimeStamp' fields are cleared.</LI>
* <LI><b>=0</b> Then the value is always cached and always valid.
* The 'value' field is returned. If there is no 'value' field
* then the operation method is invoked for the attribute.
* The 'lastUpdatedTimeStamp' field and `value' fields are set to
* the operation's return value and the current time stamp.</LI>
* <LI><b>>0</b> Represents the number of seconds that the 'value'
* field is valid.
* The 'value' field is no longer valid when
* 'lastUpdatedTimeStamp' + 'currencyTimeLimit' > Now.
* <UL>
* <LI>When 'value' is valid, 'value' is returned.</LI>
* <LI>When 'value' is no longer valid then the operation
* method is invoked. The 'lastUpdatedTimeStamp' field
* and `value' fields are updated.</lI>
* </UL>
* </LI>
* </UL>
*
* <p><b>Note:</b> because of inconsistencies in previous versions of
* this specification, it is recommended not to use negative or zero
* values for <code>currencyTimeLimit</code>. To indicate that a
* cached value is never valid, omit the
* <code>currencyTimeLimit</code> field. To indicate that it is
* always valid, use a very large number for this field.</p>
*
* @param opName The name of the method to be invoked. The
* name can be the fully qualified method name including the
* classname, or just the method name if the classname is
* defined in the 'class' field of the operation descriptor.
* @param opArgs An array containing the parameters to be set
* when the operation is invoked
* @param sig An array containing the signature of the
* operation. The class objects will be loaded using the same
* class loader as the one used for loading the MBean on which
* the operation was invoked.
*
* @return The object returned by the method, which represents the
* result of invoking the method on the specified managed resource.
*
* @exception MBeanException Wraps one of the following Exceptions:
* <UL>
* <LI> An Exception thrown by the managed object's invoked method.</LI>
* <LI> {@link ServiceNotFoundException}: No ModelMBeanOperationInfo or
* no descriptor defined for the specified operation or the managed
* resource is null.</LI>
* <LI> {@link InvalidTargetObjectTypeException}: The 'targetType'
* field value is not 'objectReference'.</LI>
* </UL>
* @exception ReflectionException Wraps an {@link java.lang.Exception}
* thrown while trying to invoke the method.
* @exception RuntimeOperationsException Wraps an
* {@link IllegalArgumentException} Method name is null.
*
**/
/*
The requirement to be able to invoke methods on the
RequiredModelMBean class itself makes this method considerably
more complicated than it might otherwise be. Note that, unlike
earlier versions, we do not allow you to invoke such methods if
they are not explicitly mentioned in the ModelMBeanInfo. Doing
so was potentially a security problem, and certainly very
surprising.
We do not look for the method in the RequiredModelMBean class
itself if:
(a) there is a "targetObject" field in the Descriptor for the
operation; or
(b) there is a "class" field in the Descriptor for the operation
and the named class is not RequiredModelMBean or one of its
superinterfaces; or
(c) the name of the operation is not the name of a method in
RequiredModelMBean (this is just an optimization).
In cases (a) and (b), if you have gone to the trouble of adding
those fields specifically for this operation then presumably you
do not want RequiredModelMBean's methods to be called.
We have to pay attention to class loading issues. If the
"class" field is present, the named class has to be resolved
relative to RequiredModelMBean's class loader to test the
condition (b) above, and relative to the managed resource's
class loader to ensure that the managed resource is in fact of
the named class (or a subclass). The class names in the sig
array likewise have to be resolved, first against
RequiredModelMBean's class loader, then against the managed
resource's class loader. There is no point in using any other
loader because when we call Method.invoke we must call it on
a Method that is implemented by the target object.
*/
public Object invoke(String opName, Object[] opArgs, String[] sig) throws MBeanException, ReflectionException {
final boolean tracing = MODELMBEAN_LOGGER.isLoggable(Level.FINER);
final String mth = "invoke(String, Object[], String[])";
if (tracing) {
MODELMBEAN_LOGGER.logp(Level.FINER, RequiredModelMBean.class.getName(), mth, "Entry");
}
if (opName == null) {
final RuntimeException x = new IllegalArgumentException("Method name must not be null");
throw new RuntimeOperationsException(x, "An exception occurred while trying to " + "invoke a method on a RequiredModelMBean");
}
String opClassName = null;
String opMethodName;
// Parse for class name and method
int opSplitter = opName.lastIndexOf(".");
if (opSplitter > 0) {
opClassName = opName.substring(0, opSplitter);
opMethodName = opName.substring(opSplitter + 1);
} else
opMethodName = opName;
/* Ignore anything after a left paren. We keep this for
compatibility but it isn't specified. */
opSplitter = opMethodName.indexOf("(");
if (opSplitter > 0)
opMethodName = opMethodName.substring(0, opSplitter);
if (tracing) {
MODELMBEAN_LOGGER.logp(Level.FINER, RequiredModelMBean.class.getName(), mth, "Finding operation " + opName + " as " + opMethodName);
}
ModelMBeanOperationInfo opInfo = modelMBeanInfo.getOperation(opMethodName);
if (opInfo == null) {
final String msg = "Operation " + opName + " not in ModelMBeanInfo";
throw new MBeanException(new ServiceNotFoundException(msg), msg);
}
final Descriptor opDescr = opInfo.getDescriptor();
if (opDescr == null) {
final String msg = "Operation descriptor null";
throw new MBeanException(new ServiceNotFoundException(msg), msg);
}
final Object cached = resolveForCacheValue(opDescr);
if (cached != null) {
if (tracing) {
MODELMBEAN_LOGGER.logp(Level.FINER, RequiredModelMBean.class.getName(), mth, "Returning cached value");
}
return cached;
}
if (opClassName == null)
opClassName = (String) opDescr.getFieldValue("class");
// may still be null now
opMethodName = (String) opDescr.getFieldValue("name");
if (opMethodName == null) {
final String msg = "Method descriptor must include `name' field";
throw new MBeanException(new ServiceNotFoundException(msg), msg);
}
final String targetTypeField = (String) opDescr.getFieldValue("targetType");
if (targetTypeField != null && !targetTypeField.equalsIgnoreCase("objectReference")) {
final String msg = "Target type must be objectReference: " + targetTypeField;
throw new MBeanException(new InvalidTargetObjectTypeException(msg), msg);
}
final Object targetObjectField = opDescr.getFieldValue("targetObject");
if (tracing && targetObjectField != null)
MODELMBEAN_LOGGER.logp(Level.FINER, RequiredModelMBean.class.getName(), mth, "Found target object in descriptor");
/* Now look for the method, either in RequiredModelMBean itself
or in the target object. Set "method" and "targetObject"
appropriately. */
Method method;
Object targetObject;
method = findRMMBMethod(opMethodName, targetObjectField, opClassName, sig);
if (method != null)
targetObject = this;
else {
if (tracing) {
MODELMBEAN_LOGGER.logp(Level.FINER, RequiredModelMBean.class.getName(), mth, "looking for method in managedResource class");
}
if (targetObjectField != null)
targetObject = targetObjectField;
else {
targetObject = managedResource;
if (targetObject == null) {
final String msg = "managedResource for invoke " + opName + " is null";
Exception snfe = new ServiceNotFoundException(msg);
throw new MBeanException(snfe);
}
}
final Class<?> targetClass;
if (opClassName != null) {
try {
AccessControlContext stack = AccessController.getContext();
final Object obj = targetObject;
final String className = opClassName;
final ClassNotFoundException[] caughtException = new ClassNotFoundException[1];
targetClass = javaSecurityAccess.doIntersectionPrivilege(new PrivilegedAction<Class<?>>() {
@Override
public Class<?> run() {
try {
ReflectUtil.checkPackageAccess(className);
final ClassLoader targetClassLoader = obj.getClass().getClassLoader();
return Class.forName(className, false, targetClassLoader);
} catch (ClassNotFoundException e) {
caughtException[0] = e;
}
return null;
}
}, stack, acc);
if (caughtException[0] != null) {
throw caughtException[0];
}
} catch (ClassNotFoundException e) {
final String msg = "class for invoke " + opName + " not found";
throw new ReflectionException(e, msg);
}
} else
targetClass = targetObject.getClass();
method = resolveMethod(targetClass, opMethodName, sig);
}
if (tracing) {
MODELMBEAN_LOGGER.logp(Level.FINER, RequiredModelMBean.class.getName(), mth, "found " + opMethodName + ", now invoking");
}
final Object result = invokeMethod(opName, method, targetObject, opArgs);
if (tracing) {
MODELMBEAN_LOGGER.logp(Level.FINER, RequiredModelMBean.class.getName(), mth, "successfully invoked method");
}
if (result != null)
cacheResult(opInfo, opDescr, result);
return result;
}
Aggregations