0

您好,最近我开始研究 JMX bean 实现。

然后我发布下面的 bean,运行 JConsole,连接到 bean,注册通知。但是,当发送通知时,我收到以下错误:

2012 年 4 月 13 日下午 5:31:26 ClientNotifForwarder NotifFetcher.fetchOneNotif 警告:无法反序列化通知:java.io.NotSerializableException:com。* .jmx.TaskMergeMBean

任何帮助都将受到欢迎,我花了一天的大部分时间试图解决这个问题。

谢谢,乔纳森

public class TaskMBean extends NotificationBroadcasterSupport implements DynamicMBean {

  private final TaskStateChangedEventListener taskChangedListener;

  public TaskMBean (DriverIf driver) {
    taskChangedListener= new TaskStateChangedEventListener (this);
    driver.registerMergeTaskStateChangedListener(mergeTaskChangedListener);
  }
  @Override
  public MBeanNotificationInfo[] getNotificationInfo() {
    String[] types = new String[] { AttributeChangeNotification.ATTRIBUTE_CHANGE };
    String name = AttributeChangeNotification.class.getName();
    String description = "An attribute of this MBean has changed";
    MBeanNotificationInfo info = new MBeanNotificationInfo(types, name,description);
    return new MBeanNotificationInfo[] { info };
  }

  @Override
  public Object getAttribute(String attribute) throws AttributeNotFoundException,          MBeanException,
      ReflectionException {
    // TODO Auto-generated method stub
    return null;
  }

  @Override
  public void setAttribute(Attribute attribute) throws AttributeNotFoundException,
      InvalidAttributeValueException, MBeanException, ReflectionException {
    // TODO Auto-generated method stub

  }

  @Override
  public AttributeList getAttributes(String[] attributes) {
    // TODO Auto-generated method stub
    return null;
  }

  @Override
  public AttributeList setAttributes(AttributeList attributes) {
    // TODO Auto-generated method stub
    return null;
  }

  @Override
  public Object invoke(String actionName, Object[] params, String[] signature)
      throws MBeanException, ReflectionException {
    // TODO Auto-generated method stub
    return null;
  }

  @Override
  public MBeanInfo getMBeanInfo() {
    MBeanNotificationInfo haltInfo =
        new MBeanNotificationInfo(
            new String[] { "NOTIFICATION_TYPE_MERGE_STATE_CHANGE" },
            Notification.class.getName(), "server halt on fatal error");
    MBeanNotificationInfo[] notifications = new MBeanNotificationInfo[] { haltInfo };
    return new OpenMBeanInfoSupport(XhiveMergeMBean.class.getName(), "", null, null, null,
        notifications);
  }
}

public class TaskStateChangedEventListener implements Serializable {

  static final String NOTIFICATION_TYPE_MERGE_STATE_CHANGE = "com.xhive.lucene.merge";
  private final NotificationBroadcasterSupport broadcaster;
  private int notificationSequence = 1;

  public TaskStateChangedEventListener (NotificationBroadcasterSupport broadcaster) {
    this.broadcaster = broadcaster;
  }

  @Override
  public void notify(Object source) {
    Notification n =
        new AttributeChangeNotification(this, notificationSequence++,    System.currentTimeMillis(), "", "", "int", 1, 2);
    broadcaster.sendNotification(n);
  }
}
4

1 回答 1

2

彼得所说的。但是也.....

通知通常(但并非总是)必须被序列化,因此使用它作为通知源往往会削弱. (双关语)

因此,您需要完全确保this的实例是可序列化的(最好是这样),或者更好的是,发送一个更简单的this表示形式,例如 MBean 的 ObjectName。目的是让接收者(或过滤器)能够确定通知的来源,所以我发现一致使用信息性 ObjectNames 确实有帮助。

最后,JConsole 在业务类上往往有点薄(我的意思是默认情况下),所以如果你非常依赖 JConsole 并且希望能够干净地查看所有通知,你需要确保你只使用有效负载中的核心 JDK 类型。

(或使用 OpenTypes(同样的事情)或启用远程类加载(不值得麻烦))。

//尼古拉斯

于 2012-04-13T20:54:17.687 回答