Details
-
Bug
-
Status: Closed
-
Critical
-
Resolution: Fixed
-
1.0-JSR-5
-
None
-
None
-
WinXp.
JDk150_06
Description
Using the GroovyMBean to access MBeans running the Oracle J2EE container (OC4J).
Some of the MBeans have overloaded methods, such as:
J2EEApplication::
testDataSource(String sqlStmt)
testDataSource(String sqlStmt, String username, String password)
When using the GroovyMBean to access this MBean its not possible to invoke testDataSource(String sqlStmt)
defaultApp.testDataSource("select * from sys.dual")
This always results in an exception on the underlying MBeanServer.
The problem is that the GroovyMBean stores a signature for each operation from its specified MBean in a HashMap, using the operation name as its key. It then later uses the method name to retrieve the signature to invoke the operation on the MBean.
88 public GroovyMBean(MBeanServerConnection server, ObjectName name) throws JMException, IOException {
89 this.server = server;
90 this.name = name;
91 this.beanInfo = server.getMBeanInfo(name);
92
93 MBeanOperationInfo[] operationInfos = beanInfo.getOperations();
94 for (int i = 0; i < operationInfos.length; i++ )
98 }
99
136 public Object invokeMethod(String method, Object arguments) {
137 String[] signature = (String[]) operations.get(method);
Thus for overloaded operations, only the last operation found will be stored in the HashMap.
If another variant of the operation is invoked on the GroovyMBean then an incorrect signature will be passed to the MBeanServer which results in an exception occuring on the server.
One simple fix is to create a unique key for the operation name consisting of the name and the number of parameters and use that to store the operation name and signature for each operation
/**
- Construct a simple key based on the method name and the number of parameters
- @param operation - the mbean operation name
- @param params - the number of parameters the operation supports
- @return simple unique identifier for a method
*/
protected String createOperationKey(String operation, int params) { // This could be changed to support some hash of the parameter types, etc. return operation + "_" + params; }
93 MBeanOperationInfo[] operationInfos = beanInfo.getOperations();
94 for (int i = 0; i < operationInfos.length; i++ )
and then change invokeMethod method to construct the operationKey from the given method and paramater length.
public Object invokeMethod(String method, Object arguments) {
// Moved this outside the try block so we can obtain the number of parameters
// specified in the arguments array, which is needed to find the correct method.
Object[] argArray = null;
if (arguments instanceof Object[])
else {
argArray = new Object[]
;
}
// Locate the specific method based on the name and number of parameters
String operationKey = createOperationKey(method,argArray.length);
String[] signature = (String[]) operations.get(operationKey);
if (signature != null) {
try
catch (MBeanException e)
{ throw new GroovyRuntimeException("Could not invoke method: " + method + ". Reason: " + e, e.getTargetException()); }catch (Exception e)
{ throw new GroovyRuntimeException("Could not invoke method: " + method + ". Reason: " + e, e); } }
else
}
Attachments
Attachments
Issue Links
- is superceded by
-
GROOVY-2807 GroovyMBean does not support the use of overloaded MBean operations that have the same number of parameters
- Open