2012-04-13 45 views
0

您好,最近我开始研究JMX bean实现。当JMX引发通知时引发java.io.NotSerializableException

然后我发布下面的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); 
    } 
} 
+1

'TaskMergeMBean'是否实现了'Serializable'? – 2012-04-13 15:41:17

回答

2

什么彼得说。但也.....

通知通常(但并不总是)必须序列,因此使用为通知源往往把一个凹痕。 (双关语意)

所以你需要完全确定的的实例这是序列化(最好是有效的话)或更好,但送什么是一个简单的表示,喜欢的ObjectName MBean。目的是让接收者(或过滤器)能够确定通知的来源,所以我发现一致地使用信息对象名称确实有帮助。

最后,JConsole在业务类(默认情况下,我的意思是)上往往有点偏薄,所以如果您依赖JConsole很多,并希望能够清晰地查看所有通知,则需要确保您只在有效负载中使用核心JDK类型。 (或使用OpenTypes(相同的东西)或启用远程类加载(不值得麻烦))。

// Nicholas