Java MXBean custom types
Asked Answered
L

2

5

I am trying to create an MXBean with a custom attribute, but I get javax.management.NotCompliantMBeanException IJmsDestinationMBean.getAttributes has parameter or return type that cannot be translated into an open type

I have read that MXBean attributes have to be OpenType compatible. How would I make my attribute work this way? All the classes below are in the same package.

class JmsDestinationMBean implements IJmsDestinationMBean{

  protected JmsDestinationAttributes attributes = new JmsDestinationAttributes();

  @Override
  public JmsDestinationAttributes getAttributes() {
    return this.attributes;
  }
}

@MXBean
interface IJmsDestinationMBean {
  JmsDestinationAttributes getAttributes()
}

class JmsDestinationAttributes {

  protected String name
  protected int messagesCurrentCount
  protected int consumersCurrentCount

  String getName() {
    this.name;
  }

  int getMessagesCurrentCount() {
    this.messagesCurrentCount;
  }

  int getConsumersCurrentCount() {
    this.consumersCurrentCount;
  }
}
Lepsy answered 18/2, 2013 at 15:7 Comment(6)
is your implementation class in the same package as your inteface ? look at this link forums.oracle.com/forums/thread.jspa?messageID=4795137.Dogtooth
They are both in the same package. I didn't find any help in that link.Lepsy
did you look at the "Posted: Sep 7, 2010 7:08 AM" it has some information about similar error you posted. The exception is the same but the main problem might be something else. I only can try to help without seeing the code it's kind of hard to debug. forums.oracle.com/forums/thread.jspa?messageID=4795137.Dogtooth
This is just a java app.Lepsy
can you tell me if you are using jre6 or jre1.6.0_01 or some other version.try using an older jre instead of jre1.6.0_01 (previous version of jre ,jre6). hope this helps and resolves your problemDogtooth
I am using JRE 1.7. What you are suggesting is more of a hack than a solution.Lepsy
E
11

The problem is the interface IJmsDestinationMBean. It returns a type JmsDestinationAttributes which is not an open type. Here's the rules-of-thumb I follow when doing this:

  • The actual registered MBean (which has a complex typed attribute) is called Foo and it's management interface is called FooMXBean.
  • The complex type (the attribute of Foo is called Bar and has a management interface called BarMBean. This guy cannot return any values that are not open types or other properly exposed complex types.

So (for this example) the "host" MBean needs to be an MXBean in order to support complex types , and the complex type needs to have an interface called <ClassName>MBean. Note that one has the MXBean interface, and the other has the MBean interface.

Here's my example:

  • JMSDestination implements JMSDestinationMXBean
  • JmsDestinationAttributes implements JmsDestinationAttributesMBean

...apologies for the loose case standard. It's an on the fly example.

Here the JMSDestination code, with a main to create and register. I am simply using the user name property to provide the name.:

public class JmsDestination implements JmsDestinationMXBean {
    protected JmsDestinationAttributes attrs = new JmsDestinationAttributes(System.getProperty("user.name"));

    public JmsDestinationAttributes getAttributes() {
        return attrs;
    }

    public static void main(String[] args) {
        JmsDestination impl = new JmsDestination();
        try {
            ManagementFactory.getPlatformMBeanServer().registerMBean(impl, new ObjectName("org.jms.impl.test:name=" + impl.attrs.getName()));
            Thread.currentThread().join();
        } catch (Exception ex) {
            ex.printStackTrace(System.err);
        }
    }
}

The JMSDestinationMXBean code:

public interface JmsDestinationMXBean {
    public JmsDestinationAttributes getAttributes();
}

The JmsDestinationAttributes code which uses the same name and random numbers for the values:

public class JmsDestinationAttributes implements JmsDestinationAttributesMBean {
    protected final String name;
    protected final Random random = new Random(System.currentTimeMillis());
    public JmsDestinationAttributes(String name) {
        this.name = name;
    }
    public String getName() {
        return name;
    }

    public int getMessagesCurrentCount() {
        return Math.abs(random.nextInt(100));
    }

    public int getConsumersCurrentCount() {
        return Math.abs(random.nextInt(10));
    }
}

.... and the JmsDestinationAttributesMBean:

public interface JmsDestinationAttributesMBean {
    public String getName();
    public int getMessagesCurrentCount();
    public int getConsumersCurrentCount();
}

The JConsole view looks like this:

JConsole view of the MXBean

The JConsole view of the MXBean's attributes looks like this:

JConsole view of the MXBean's Attributes

Make sense ?

Epiglottis answered 18/2, 2013 at 16:32 Comment(4)
Thanks! I was missing an interface for my custom type.Lepsy
One may have to activate JMX to be able to access the custom MBean via jconsole.Rude
Be sure to follow Nicholas' example and define the getter method as public JmsDestinationAttributes getAttributes();, specifying the implementation class as return type. Using public JmsDestinationAttributesMBean getAttributes(); would not work (using the interface as return type). Kinda weird, but hey.Rude
For benefit of others: I had similar requirement and Nicholas reply helped. But you have to add @ConstructorProperties({"name"}) just before constructor of JmsDestinationAttributes or you may get run-time error. Further I could even return arrays of objects from the custom type methods.Behest
E
0

Some additions to @Nicholas answer

Here it is very good Oracle documentation on MXBean

There are two ways to deserialize MXBeans :

  1. Create a static method in the bean, then that method is called to reconstruct an instance of J.

    public static J from(CompositeData cd)

  2. Or if J has at least one public constructor with either @javax.management.ConstructorParameters or @java.beans.ConstructoProperties annotation, then one of those constructors (not necessarily always the same one) will be called to reconstruct an instance of J.

Exemplary answered 30/11, 2023 at 9:1 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.