Can JMX operations take interfaces as parameters?

Posted by Thor84no on Stack Overflow See other posts from Stack Overflow or by Thor84no
Published on 2012-06-26T09:55:34Z Indexed on 2012/07/02 15:16 UTC
Read the original article Hit count: 177

Filed under:
|
|

I'm having problems with an MBean that takes a Map<String, Object> as a parameter. If I try to execute it via JMX using a proxy object, I get an Exception:

Caused by: javax.management.ReflectionException
    at org.jboss.mx.server.AbstractMBeanInvoker.invoke(AbstractMBeanInvoker.java:231)
    at org.jboss.mx.server.MBeanServerImpl.invoke(MBeanServerImpl.java:668)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
Caused by: java.lang.IllegalArgumentException: Unable to find operation updateProperties(java.util.HashMap)

It appears that it attempts to use the actual implementation class rather than the interface, and doesn't check if this is a child of the required interface. The same thing happens for extended classes (for example declare HashMap, pass in LinkedHashMap). Does this mean it's impossible to use an interface for such methods? At the moment I'm getting around it by changing the method signature to accept a HashMap, but it seems odd that I wouldn't be able to use interfaces (or extended classes) in my MBeans.

Edit: The proxy object is being created by an in-house utility class called JmxInvocationHandler. The (hopefully) relevant parts of it are as follows:

public class JmxInvocationHandler implements InvocationHandler
{
    ...
    public static <T> T createMBean(final Class<T> iface, SFSTestProperties properties, String mbean, int shHostID)
    {
        T newProxyInstance = (T) Proxy.newProxyInstance(iface.getClassLoader(), new Class[] { iface }, (InvocationHandler) new JmxInvocationHandler(properties, mbean, shHostID));
        return newProxyInstance;
    }
    ...
    private JmxInvocationHandler(SFSTestProperties properties, String mbean, int shHostID)
    {
        this.mbeanName = mbean + MBEAN_SUFFIX + shHostID;
        msConfig = new MsConfiguration(properties.getHost(0), properties.getMSAdminPort(), properties.getMSUser(), properties.getMSPassword());
    }
    ...
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
    {
        if (management == null)
        {
            management = ManagementClientStore.getInstance().getManagementClient(msConfig.getHost(),
                    msConfig.getAdminPort(), msConfig.getUser(), msConfig.getPassword(), false);
        }

        final Object result =  management.methodCall(mbeanName, method.getName(), args ==  null?  new Object[] {} : args);
        return result;
    }
}

© Stack Overflow or respective owner

Related posts about java

Related posts about jmx