【问题标题】:Java MXBean custom typesJava MXBean 自定义类型
【发布时间】:2013-02-18 15:07:09
【问题描述】:

我正在尝试使用自定义属性创建 MXBean,但我得到 javax.management.NotCompliantMBeanException IJmsDestinationMBean.getAttributes 具有无法转换为开放类型的参数或返回类型

我已阅读到 MXBean 属性必须与 OpenType 兼容。 我将如何使我的属性以这种方式工作? 以下所有类都在同一个包中。

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;
  }
}

【问题讨论】:

  • 您的实现类是否与您的接口在同一个包中?看看这个链接forums.oracle.com/forums/thread.jspa?messageID=4795137
  • 它们都在同一个包中。我在该链接中没有找到任何帮助。
  • 您是否查看过“发布时间:2010 年 9 月 7 日上午 7:08”,其中包含有关您发布的类似错误的一些信息。例外是相同的,但主要问题可能是其他问题。我只能在没有看到很难调试的代码的情况下尝试提供帮助。 forums.oracle.com/forums/thread.jspa?messageID=4795137.
  • 这只是一个java应用程序。
  • 您能告诉我您使用的是 jre6 还是 jre1.6.0_01 或其他版本。尝试使用较旧的 jre 而不是 jre1.6.0_01(以前的 jre 版本,jre6)。希望这有助于并解决您的问题

标签: java jmx mbeans


【解决方案1】:

问题是接口IJmsDestinationMBean。它返回一个类型 JmsDestinationAttributes ,它不是开放类型。以下是我在执行此操作时遵循的经验法则:

  • 实际注册的 MBean(具有复杂的类型属性)称为 Foo,其管理接口称为 FooMXBean
  • 复杂类型(Foo的属性叫Bar,有一个管理接口叫BarMBean。这家伙不能返回任何不是开放类型或其他正确公开的复杂类型的值。

因此(对于本示例)“主机”MBean 需要是 MXBean 才能支持复杂类型,并且复杂类型需要有一个名为 MBean 的接口。请注意,一个有 MXBean 接口,另一个有 MBean 接口。

这是我的例子:

  • JMSDestination 实现 JMSDestinationMXBean
  • JmsDestinationAttributes 实现 JmsDestinationAttributesMBean

...为松散的案例标准道歉。这是一个即时示例。

这里是 JMSDestination 代码,用 ma​​in 创建和注册。我只是使用用户名属性来提供名称。:

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);
        }
    }
}

JMSDestinationMXBean 代码:

public interface JmsDestinationMXBean {
    public JmsDestinationAttributes getAttributes();
}

使用相同名称和随机数作为值的 JmsDestinationAttributes 代码:

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));
    }
}

.... 和 JmsDestinationAttributesMBean:

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

JConsole 视图如下所示:

MXBean 属性的 JConsole 视图如下所示:

有意义吗?

【讨论】:

  • 谢谢!我缺少自定义类型的接口。
  • 可能必须activate JMX 才能通过 jconsole 访问自定义 MBean。
  • 请务必按照 Nicholas 的示例,将 getter 方法定义为 public JmsDestinationAttributes getAttributes();,并将 实现类 指定为返回类型。使用 public JmsDestinationAttributesMBean getAttributes(); 将不起作用(使用 interface 作为返回类型)。有点奇怪,但是嘿。
  • 为了他人的利益:我有类似的要求,尼古拉斯的回复有帮助。但是您必须在 JmsDestinationAttributes 的构造函数之前添加 @ConstructorProperties({"name"}) ,否则您可能会遇到运行时错误。此外,我什至可以从自定义类型方法返回对象数组。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-10-07
  • 1970-01-01
  • 1970-01-01
  • 2021-01-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多