4 Replies Latest reply on Apr 3, 2003 9:08 PM by Adrian Brock

    What is wrong with ModelMBean and what is the difference wit

    Alexander Rabinowitz Newbie

      I am using JBoss 3.0.6.

      I am trying to implement the same MBean as DynamicMBean and as ModelMBean.

      I call it both times the same way from my code:
      String pulsarName = "com.peerdirect.rmapplications.master.jmx.PulsarStandard" ;
      Object pulsar = Class.forName (pulsarName).newInstance();
      String name = myMBeanServer.getDefaultDomain() + ":type=" + pulsarName;
      myMBeanServer.registerMBean (pulsar, new ObjectName(name)); // line 67

      When I implement it as a DynamicMBean, it works OK.
      Here is the implementation:
      ------------- start of implementation -------------------
      package com.peerdirect.rmapplications.master.jmx;

      import com.peerdirect.rmapplications.master.jms.StatusNotificationClient;

      import javax.management.*;
      import javax.management.modelmbean.*;
      import java.util.Iterator;
      import java.lang.Runnable;
      import java.io.*;
      import org.jboss.mx.modelmbean.*;
      import org.jboss.mx.modelmbean.ModelMBeanConstants.*;

      public class PulsarStandard extends NotificationBroadcasterSupport
      implements DynamicMBean, Runnable

      {
      // support for generic notification listeners
      private NotificationBroadcasterSupport notifier = new NotificationBroadcasterSupport();

      // sequence numbers for notifications
      protected long notifierSequence = 0;
      protected long attrNotifierSequence = 0;

      // mgmt attribute name constants
      final static String PULSE_PERIOD = "PulsePeriodInMills";
      final static String IF_STARTED = "Started";

      // mgmt operation name constants
      final static String START_PULSE = "startPulse";
      final static String STOP_PULSE = "stopPulse";

      // fields for attribute values
      private static final int DEFAULT_PULSE_PERIOD = 1000;
      private static final boolean DEFAULT_STARTED= false;

      private int mPulsePeriod = 0;
      private boolean mStarted = false;
      private StatusNotificationClient mSNC = null;
      private Thread mThread = null;

      // getAttribute implementation

      public PulsarStandard () throws MBeanException
      {
      System.out.println ("PulsarStandard");
      mPulsePeriod = DEFAULT_PULSE_PERIOD;
      mStarted = DEFAULT_STARTED;
      mSNC = new StatusNotificationClient ();
      mThread = new Thread (this);
      startPulse () ;
      }

      public Object getAttribute(String attribute) throws AttributeNotFoundException, MBeanException, ReflectionException
      {
      System.out.println ("getAttribute");
      if (attribute == null || attribute.equals(""))
      throw new IllegalArgumentException("null or empty attribute name");

      // map the named attributes to fields

      if (attribute.equals(PULSE_PERIOD))
      return new Integer (mPulsePeriod);
      else if (attribute.equals(IF_STARTED))
      return new Boolean (mStarted);

      throw new AttributeNotFoundException("Attribute " + attribute + " not found.");
      }


      // getAttributes implementation

      public AttributeList getAttributes (String[] attributes)
      {
      System.out.println ("getAttributes");
      if (attributes == null)
      throw new IllegalArgumentException("null array");

      AttributeList list = new AttributeList();

      for (int i = 0; i < attributes.length; ++i)
      {
      try
      {
      list.add (new Attribute (attributes, getAttribute(attributes)));
      }
      catch (JMException ignored)
      {
      // if the attribute could not be retrieved, skip it
      }
      }
      return list;
      }


      // setAttribute implementation

      public void setAttribute (Attribute attribute) throws AttributeNotFoundException, InvalidAttributeValueException,
      MBeanException, ReflectionException
      {
      System.out.println ("setAttribute");
      if (attribute == null) throw new
      AttributeNotFoundException("null attribute");

      // map attributes to fields
      try
      {
      if (attribute.getName().equals(PULSE_PERIOD))
      this.mPulsePeriod = ((Integer)attribute.getValue()).intValue();
      else if (attribute.getName().equals(IF_STARTED))
      this.mStarted = ((Boolean)attribute.getValue()).booleanValue();
      else
      throw new AttributeNotFoundException("attribute " + attribute.getName() + " not found.");
      }
      catch (ClassCastException e)
      {
      throw new InvalidAttributeValueException("Invalid attribute type " + attribute.getValue().getClass().getName());
      }
      }


      // setAttributes implementation

      public AttributeList setAttributes (AttributeList list)
      {
      System.out.println ("setAttributes");
      if (list == null)
      throw new IllegalArgumentException("null list");

      AttributeList results = new AttributeList();
      Iterator it = list.iterator();

      while (it.hasNext())
      {
      try
      {
      Attribute attr = (Attribute)it.next();
      setAttribute(attr);
      results.add(attr);
      }
      catch (JMException ignored)
      {
      // if unable to set the attribute, skip it
      }
      }
      return results;
      }


      // invoke implementation

      public Object invoke(String actionName,
      Object[] params,
      String[] signature) throws MBeanException, ReflectionException {
      System.out.println ("invoke");
      if (actionName == null || actionName.equals(""))
      throw new IllegalArgumentException("no operation");

      // map operation names to methods
      if (actionName.equals(START_PULSE))
      {
      startPulse();
      return null;
      }
      else if (actionName.equals(STOP_PULSE))
      {
      stopPulse ();
      return null;
      }
      else
      throw new UnsupportedOperationException("unknown operation " + actionName);
      }


      // getMBeanInfo implementation
      /*public static MBeanInfo getMBeanInfo()
      {
      return getMBeanInfo1();
      }*/

      public MBeanInfo getMBeanInfo()
      {
      System.out.println ("getMBeanInfo");
      final boolean IS_READABLE = true;
      final boolean IS_WRITABLE = true;
      final boolean IS_IS = true;

      // MBean class and description
      //String className = getClass().getName();
      String className = PulsarStandard.class.getName();
      String description =
      "User resource with dynamic management interface";

      // meta data for 'PULSE_PERIOD' attribute.
      MBeanAttributeInfo mPulsePeriod = new MBeanAttributeInfo(
      PULSE_PERIOD, // name
      int.class.getName(), // type
      "Pulse Period", // description
      IS_READABLE, IS_WRITABLE, !IS_IS // access
      );

      // meta data for 'IF_STARTED' attribute.
      MBeanAttributeInfo mStarted = new MBeanAttributeInfo(
      IF_STARTED, // name
      boolean.class.getName(), // type
      "If the Pulser has Started", // description
      IS_READABLE, !IS_WRITABLE, !IS_IS // access
      );

      // meta data for 'startPulse' operation
      MBeanOperationInfo startPulse = new MBeanOperationInfo(
      START_PULSE, // name
      "Start the pulsar", // description
      null, // signature
      void.class.getName(), // return type
      MBeanOperationInfo.ACTION // impact
      );

      // meta data for 'stopPulse' operation
      MBeanOperationInfo stopPulse = new MBeanOperationInfo(
      STOP_PULSE, // name
      "Stop the pulsar", // description
      null, // signature
      void.class.getName(), // return type
      MBeanOperationInfo.ACTION // impact
      );

      // mbean constructors
      MBeanConstructorInfo defaultConstructor =
      new MBeanConstructorInfo(
      "Default Constructor",
      "Creates a new Pulsar", null
      );

      // attribute, constructor and operation lists
      MBeanAttributeInfo[] attributes = new MBeanAttributeInfo[] {mPulsePeriod, mStarted};

      MBeanConstructorInfo[] constructors = new MBeanConstructorInfo[] {defaultConstructor};

      MBeanOperationInfo[] operations = new MBeanOperationInfo[] {startPulse, stopPulse};

      // return the MBeanInfo
      return new MBeanInfo (className, description, attributes, constructors, operations, null);
      }

      public void startPulse ()
      {
      System.out.println ("startPulse");
      mThread.start ();
      try
      {
      mSNC.connect();
      mStarted = true ;
      }
      catch (Exception e)
      {
      mStarted = false ;
      }
      }

      public void stopPulse ()
      {
      System.out.println ("stopPulse");
      mThread.stop ();
      mSNC.disconnect();
      mStarted = false ;
      }

      public void run ()
      {
      System.out.println ("run");
      try
      {
      while (true)
      {
      mThread.sleep (mPulsePeriod);
      if (mStarted)
      {
      System.out.println("Pulsing");
      mSNC.sendPulse();
      }
      }
      }
      catch (Exception ex)
      {
      ex.printStackTrace();
      }
      }
      }

      //////////////////////////////////////////////////////////////////////////////////////
      //////////////////////////////////////////////////////////////////////////////////////
      //////////////////////////////////////////////////////////////////////////////////////
      ----------------- end of implementation ---------------

      However, whan I implement it as a ModelMBean (not directly ModelMBean, because I need to use PersistPolicy; I tried to implement it as ModelBase or as XMBean - both times) it does not wortk - it bring out an exception (which is not brough out when I use DynamicMBean implementation of the same Mbean):

      MBeanException: preRegister() failed
      [ObjectName='DefaultDomain:type=com.peerdirect.rmapplications.master.jmx.PulsarStandard',Class=com.peerdirect.rmapplications.master.jmx.PulsarStandard
      (com.peerdirect.rmapplications.master.jmx.PulsarStandard@5bdc50)]
      Cause: java.lang.NullPointerException
      at
      org.jboss.mx.server.registry.BasicMBeanRegistry.registerMBean(BasicMBeanRegistry.java:187)
      at org.jboss.mx.server.MBeanServerImpl.registerMBean(MBeanServerImpl.java:975)
      at org.jboss.mx.server.MBeanServerImpl.registerMBean(MBeanServerImpl.java:302)
      at com.peerdirect.rmapplications.agent.BaseAgent.(BaseAgent.java:67)
      at com.peerdirect.rmapplications.agent.MasterAgent.(MasterAgent.java:5)
      at com.peerdirect.rmapplications.agent.MasterAgent.main(MasterAgent.java:15)

      Here is my implementation as ModelBase (absolutely the same thing happens when I use XMBean instead of ModelBase):
      --------------------- start of implementation --------
      package com.peerdirect.rmapplications.master.jmx;

      import com.peerdirect.rmapplications.master.jms.StatusNotificationClient;

      import javax.management.*;
      import javax.management.modelmbean.*;
      import java.util.Iterator;
      import java.lang.Runnable;
      import java.io.*;
      import org.jboss.mx.modelmbean.*;
      import org.jboss.mx.modelmbean.ModelMBeanConstants.*;

      public class PulsarStandard extends ModelBase
      implements Runnable
      {
      // support for generic notification listeners
      private NotificationBroadcasterSupport notifier = new NotificationBroadcasterSupport();

      // sequence numbers for notifications
      protected long notifierSequence = 0;
      protected long attrNotifierSequence = 0;

      // mgmt attribute name constants
      final static String PULSE_PERIOD = "PulsePeriodInMills";
      final static String IF_STARTED = "Started";

      // mgmt operation name constants
      final static String START_PULSE = "startPulse";
      final static String STOP_PULSE = "stopPulse";

      // fields for attribute values
      private static final int DEFAULT_PULSE_PERIOD = 1000;
      private static final boolean DEFAULT_STARTED= false;

      private int mPulsePeriod = 0;
      private boolean mStarted = false;
      private StatusNotificationClient mSNC = null;
      private Thread mThread = null;

      protected ModelMBeanInfo metadata = null;
      protected Object resource = null;
      protected String resourceType = null;

      public boolean isSupportedResourceType(String resourceType)
      {
      System.out.println("isSupportedResourceType");
      return true;
      }

      // getAttribute implementation

      public PulsarStandard () throws MBeanException
      {
      super ();
      System.out.println ("PulsarStandard");
      mPulsePeriod = DEFAULT_PULSE_PERIOD;
      mStarted = DEFAULT_STARTED;
      mSNC = new StatusNotificationClient ();
      mThread = new Thread (this);
      startPulse () ;
      }

      public Object getAttribute(String attribute) throws AttributeNotFoundException, MBeanException, ReflectionException
      {
      System.out.println ("getAttribute");
      if (attribute == null || attribute.equals(""))
      throw new IllegalArgumentException("null or empty attribute name");

      // map the named attributes to fields

      if (attribute.equals(PULSE_PERIOD))
      return new Integer (mPulsePeriod);
      else if (attribute.equals(IF_STARTED))
      return new Boolean (mStarted);

      throw new AttributeNotFoundException("Attribute " + attribute + " not found.");
      }


      // getAttributes implementation

      public AttributeList getAttributes (String[] attributes)
      {
      System.out.println ("getAttributes");
      if (attributes == null)
      throw new IllegalArgumentException("null array");

      AttributeList list = new AttributeList();

      for (int i = 0; i < attributes.length; ++i)
      {
      try
      {
      list.add (new Attribute (attributes, getAttribute(attributes)));
      }
      catch (JMException ignored)
      {
      // if the attribute could not be retrieved, skip it
      }
      }
      return list;
      }


      // setAttribute implementation

      public void setAttribute (Attribute attribute) throws AttributeNotFoundException, InvalidAttributeValueException,
      MBeanException, ReflectionException
      {
      System.out.println ("setAttribute");
      if (attribute == null) throw new
      AttributeNotFoundException("null attribute");

      // map attributes to fields
      try
      {
      if (attribute.getName().equals(PULSE_PERIOD))
      this.mPulsePeriod = ((Integer)attribute.getValue()).intValue();
      else if (attribute.getName().equals(IF_STARTED))
      this.mStarted = ((Boolean)attribute.getValue()).booleanValue();
      else
      throw new AttributeNotFoundException("attribute " + attribute.getName() + " not found.");
      }
      catch (ClassCastException e)
      {
      throw new InvalidAttributeValueException("Invalid attribute type " + attribute.getValue().getClass().getName());
      }
      }


      // setAttributes implementation

      public AttributeList setAttributes (AttributeList list)
      {
      System.out.println ("setAttributes");
      if (list == null)
      throw new IllegalArgumentException("null list");

      AttributeList results = new AttributeList();
      Iterator it = list.iterator();

      while (it.hasNext())
      {
      try
      {
      Attribute attr = (Attribute)it.next();
      setAttribute(attr);
      results.add(attr);
      }
      catch (JMException ignored)
      {
      // if unable to set the attribute, skip it
      }
      }
      return results;
      }


      // invoke implementation

      public Object invoke(String actionName,
      Object[] params,
      String[] signature) throws MBeanException, ReflectionException {
      System.out.println ("invoke");
      if (actionName == null || actionName.equals(""))
      throw new IllegalArgumentException("no operation");

      // map operation names to methods
      if (actionName.equals(START_PULSE))
      {
      startPulse();
      return null;
      }
      else if (actionName.equals(STOP_PULSE))
      {
      stopPulse ();
      return null;
      }
      else
      throw new UnsupportedOperationException("unknown operation " + actionName);
      }


      // getMBeanInfo implementation
      /*public static MBeanInfo getMBeanInfo()
      {
      return getMBeanInfo1();
      }*/

      public MBeanInfo getMBeanInfo()
      {
      System.out.println ("getMBeanInfo");
      //final boolean IS_READABLE = true;
      //final boolean IS_WRITABLE = true;
      //final boolean IS_IS = true;

      // MBean class and description
      //String className = getClass().getName();
      String className = PulsarStandard.class.getName();
      String description =
      "User resource with model management interface";

      // build 'RoomName' read-write attribute
      /*Descriptor descr_my = new DescriptorSupport();
      descr_my.setField(PERSIST_POLICY, "OnUpdate");
      descr_my.setField(PERSIST_LOCATION, "c:\\aa");
      descr_my.setField(PERSIST_NAME, "storage.txt");
      System.out.println ("Valid " + descr_my.isValid());*/

      // meta data for 'PULSE_PERIOD' attribute.
      ModelMBeanAttributeInfo mPulsePeriod = new ModelMBeanAttributeInfo(
      PULSE_PERIOD, // name
      int.class.getName(), // type
      "Pulse Period", // description
      IS_READABLE, IS_WRITABLE, !IS_IS//, // access
      //descr_my
      );

      // meta data for 'IF_STARTED' attribute.
      ModelMBeanAttributeInfo mStarted = new ModelMBeanAttributeInfo(
      IF_STARTED, // name
      boolean.class.getName(), // type
      "If the Pulser has Started", // description
      IS_READABLE, !IS_WRITABLE, !IS_IS // access
      );

      // meta data for 'startPulse' operation
      ModelMBeanOperationInfo startPulse = new ModelMBeanOperationInfo(
      START_PULSE, // name
      "Start the pulsar", // description
      null, // signature
      void.class.getName(), // return type
      MBeanOperationInfo.ACTION // impact
      );

      // meta data for 'stopPulse' operation
      ModelMBeanOperationInfo stopPulse = new ModelMBeanOperationInfo(
      STOP_PULSE, // name
      "Stop the pulsar", // description
      null, // signature
      void.class.getName(), // return type
      MBeanOperationInfo.ACTION // impact
      );

      // mbean constructors
      ModelMBeanConstructorInfo defaultConstructor =
      new ModelMBeanConstructorInfo(
      "Default Constructor",
      "Creates a new Pulsar", null
      );

      // attribute, constructor and operation lists
      ModelMBeanAttributeInfo[] attributes = new ModelMBeanAttributeInfo[] {mPulsePeriod, mStarted};

      ModelMBeanConstructorInfo[] constructors = new ModelMBeanConstructorInfo[] {defaultConstructor};

      ModelMBeanOperationInfo[] operations = new ModelMBeanOperationInfo[] {startPulse, stopPulse};

      // return the MBeanInfo
      return new ModelMBeanInfoSupport (className, description, attributes, constructors, operations, null);
      }

      // RW attributes
      /*
      public int getPulsePeriodInMills ()
      {
      return mPulsePeriod;
      }

      public void setPulsePeriodInMills (int pPulsePeriod)
      {
      mPulsePeriod = pPulsePeriod ;
      }

      public boolean getStarted ()
      {
      return mStarted;
      }
      */

      public void startPulse ()
      {
      System.out.println ("startPulse");
      mThread.start ();
      try
      {
      mSNC.connect();
      mStarted = true ;
      }
      catch (Exception e)
      {
      mStarted = false ;
      }
      }

      public void stopPulse ()
      {
      System.out.println ("stopPulse");
      mThread.stop ();
      mSNC.disconnect();
      mStarted = false ;
      }

      public void run ()
      {
      System.out.println ("run");
      try
      {
      while (true)
      {
      mThread.sleep (mPulsePeriod);
      if (mStarted)
      {
      System.out.println("Pulsing");
      mSNC.sendPulse();
      }
      }
      }
      catch (Exception ex)
      {
      ex.printStackTrace();
      }
      }
      }

      //////////////////////////////////////////////////////////////////////////////////////
      //////////////////////////////////////////////////////////////////////////////////////
      //////////////////////////////////////////////////////////////////////////////////////
      --------------------- end of implementation --------

        • 1. Re: What is wrong with ModelMBean and what is the difference
          Adrian Brock Master

          Typically a modelmbean is used in the following
          way (example from testsuite):

          Resource resource = new Resource();
          ModelMBean modelmbean = new RequiredModelMBean();
          modelmbean.setModelMBeanInfo(getModelMBeanInfo());
          modelmbean.setManagedResource(resource, "ObjectReference");

          ObjectName name = new ObjectName("rmm:invocationTest=true");
          server.registerMBean(modelmbean, name);

          Where getModelMBeanInfo() creates the
          meta data.

          With your current code you would have
          to use the
          ModelBase(ModelMBeanInfo) constructor

          instead of super()

          Regards,
          Adrian

          • 2. Re: What is wrong with ModelMBean and what is the difference
            Alexander Rabinowitz Newbie

            I just changed the code to incorporated those changes.

            I still have the following problem:
            MBeanException: preRegister() failed [ObjectName='DefaultDomain:type=com.peerdir
            ect.rmapplications.master.jmx.PulsarStandard', Class=com.peerdirect.rmapplicatio
            ns.master.jmx.PulsarStandard (com.peerdirect.rmapplications.master.jmx.PulsarSta
            ndard@3020ad)]
            Cause: ReflectionException: null
            Cause: javax.management.IntrospectionException: no method found for operation: startPulse
            at org.jboss.mx.server.registry.BasicMBeanRegistry.registerMBean(BasicMBeanRegistry.java:187)
            at org.jboss.mx.server.MBeanServerImpl.registerMBean(MBeanServerImpl.java:975)
            at org.jboss.mx.server.MBeanServerImpl.registerMBean(MBeanServerImpl.java:302)
            at com.peerdirect.rmapplications.agent.BaseAgent.(BaseAgent.java:67)
            at com.peerdirect.rmapplications.agent.MasterAgent.(MasterAgent.java:5)
            at com.peerdirect.rmapplications.agent.MasterAgent.main(MasterAgent.java:15)

            Now my constructor looks the following way:

            public PulsarStandard () throws MBeanException
            {
            super (createMBeanInfo());
            System.out.println ("PulsarStandard");
            try
            {
            setManagedResource (new Object (), OBJECT_REF);
            }
            catch (Exception e)
            {
            e.printStackTrace();
            }
            mPulsePeriod = DEFAULT_PULSE_PERIOD;
            mStarted = DEFAULT_STARTED;
            mSNC = new StatusNotificationClient ();
            mThread = new Thread (this);
            startPulse () ;
            }
            While the following methods look like:

            // getMBeanInfo implementation
            public MBeanInfo getMBeanInfo()
            {
            return info;
            }

            public static /*MBeanInfo*/ ModelMBeanInfo createMBeanInfo()
            {
            System.out.println ("getMBeanInfo");
            //final boolean IS_READABLE = true;
            //final boolean IS_WRITABLE = true;
            //final boolean IS_IS = true;

            // MBean class and description
            //String className = getClass().getName();
            String className = PulsarStandard.class.getName();
            String description =
            "User resource with model management interface";

            // build 'RoomName' read-write attribute
            /*Descriptor descr_my = new DescriptorSupport();
            descr_my.setField(PERSIST_POLICY, "OnUpdate");
            descr_my.setField(PERSIST_LOCATION, "c:\\aa");
            descr_my.setField(PERSIST_NAME, "storage.txt");
            System.out.println ("Valid " + descr_my.isValid());*/

            // meta data for 'PULSE_PERIOD' attribute.
            ModelMBeanAttributeInfo mPulsePeriod = new ModelMBeanAttributeInfo(
            PULSE_PERIOD, // name
            int.class.getName(), // type
            "Pulse Period", // description
            IS_READABLE, IS_WRITABLE, !IS_IS//, // access
            //descr_my
            );

            // meta data for 'IF_STARTED' attribute.
            ModelMBeanAttributeInfo mStarted = new ModelMBeanAttributeInfo(
            IF_STARTED, // name
            boolean.class.getName(), // type
            "If the Pulser has Started", // description
            IS_READABLE, !IS_WRITABLE, !IS_IS // access
            );

            // meta data for 'startPulse' operation
            ModelMBeanOperationInfo startPulse = new ModelMBeanOperationInfo(
            START_PULSE, // name
            "Start the pulsar", // description
            null, // signature
            void.class.getName(), // return type
            MBeanOperationInfo.ACTION // impact
            );

            // meta data for 'stopPulse' operation
            ModelMBeanOperationInfo stopPulse = new ModelMBeanOperationInfo(
            STOP_PULSE, // name
            "Stop the pulsar", // description
            null, // signature
            void.class.getName(), // return type
            MBeanOperationInfo.ACTION // impact
            );

            // mbean constructors
            ModelMBeanConstructorInfo defaultConstructor =
            new ModelMBeanConstructorInfo(
            "Default Constructor",
            "Creates a new Pulsar", null
            );

            // attribute, constructor and operation lists
            ModelMBeanAttributeInfo[] attributes = new ModelMBeanAttributeInfo[] {mPulsePeriod, mStarted};

            ModelMBeanConstructorInfo[] constructors = new ModelMBeanConstructorInfo[] {defaultConstructor};

            ModelMBeanOperationInfo[] operations = new ModelMBeanOperationInfo[] {startPulse, stopPulse};

            // return the MBeanInfo
            return new ModelMBeanInfoSupport (className, description, attributes, constructors, operations, null);
            }
            I stll call the bean in the following way,

            String pulsarName = "com.peerdirect.rmapplications.master.jmx.PulsarStandard" ;
            Object pulsar = Class.forName (pulsarName).newInstance();
            String name = myMBeanServer.getDefaultDomain() + ":type=" + pulsarName;
            myMBeanServer.registerMBean (pulsar, new ObjectName(name)); // line 67

            however, the constructor does the rest of the changes you specifically mentioned.

            Now my class looks like:
            --------------- start ----------------------------
            package com.peerdirect.rmapplications.master.jmx;

            import com.peerdirect.rmapplications.master.jms.StatusNotificationClient;

            import javax.management.*;
            import javax.management.modelmbean.*;
            import java.util.Iterator;
            import java.lang.Runnable;
            import java.io.*;
            import org.jboss.mx.modelmbean.*;
            import org.jboss.mx.modelmbean.ModelMBeanConstants.*;

            public class PulsarStandard extends ModelBase
            implements Runnable
            {
            // support for generic notification listeners
            private NotificationBroadcasterSupport notifier = new NotificationBroadcasterSupport();

            // sequence numbers for notifications
            protected long notifierSequence = 0;
            protected long attrNotifierSequence = 0;

            // mgmt attribute name constants
            final static String PULSE_PERIOD = "PulsePeriodInMills";
            final static String IF_STARTED = "Started";

            // mgmt operation name constants
            final static String START_PULSE = "startPulse";
            final static String STOP_PULSE = "stopPulse";

            // fields for attribute values
            private static final int DEFAULT_PULSE_PERIOD = 1000;
            private static final boolean DEFAULT_STARTED= false;

            private int mPulsePeriod = 0;
            private boolean mStarted = false;
            private StatusNotificationClient mSNC = null;
            private Thread mThread = null;

            protected ModelMBeanInfo metadata = null;
            protected Object resource = null;
            protected String resourceType = null;

            public boolean isSupportedResourceType(String resourceType)
            {
            System.out.println("isSupportedResourceType");
            return true;
            }

            // getAttribute implementation

            public PulsarStandard () throws MBeanException
            {
            super (createMBeanInfo());
            System.out.println ("PulsarStandard");
            try
            {
            setManagedResource (new Object (), OBJECT_REF);
            }
            catch (Exception e)
            {
            e.printStackTrace();
            }
            mPulsePeriod = DEFAULT_PULSE_PERIOD;
            mStarted = DEFAULT_STARTED;
            mSNC = new StatusNotificationClient ();
            mThread = new Thread (this);
            startPulse () ;
            }

            public Object getAttribute(String attribute) throws AttributeNotFoundException, MBeanException, ReflectionException
            {
            System.out.println ("getAttribute");
            if (attribute == null || attribute.equals(""))
            throw new IllegalArgumentException("null or empty attribute name");

            // map the named attributes to fields

            if (attribute.equals(PULSE_PERIOD))
            return new Integer (mPulsePeriod);
            else if (attribute.equals(IF_STARTED))
            return new Boolean (mStarted);

            throw new AttributeNotFoundException("Attribute " + attribute + " not found.");
            }


            // getAttributes implementation

            public AttributeList getAttributes (String[] attributes)
            {
            System.out.println ("getAttributes");
            if (attributes == null)
            throw new IllegalArgumentException("null array");

            AttributeList list = new AttributeList();

            for (int i = 0; i < attributes.length; ++i)
            {
            try
            {
            list.add (new Attribute (attributes, getAttribute(attributes)));
            }
            catch (JMException ignored)
            {
            // if the attribute could not be retrieved, skip it
            }
            }
            return list;
            }


            // setAttribute implementation

            public void setAttribute (Attribute attribute) throws AttributeNotFoundException, InvalidAttributeValueException,
            MBeanException, ReflectionException
            {
            System.out.println ("setAttribute");
            if (attribute == null) throw new
            AttributeNotFoundException("null attribute");

            // map attributes to fields
            try
            {
            if (attribute.getName().equals(PULSE_PERIOD))
            this.mPulsePeriod = ((Integer)attribute.getValue()).intValue();
            else if (attribute.getName().equals(IF_STARTED))
            this.mStarted = ((Boolean)attribute.getValue()).booleanValue();
            else
            throw new AttributeNotFoundException("attribute " + attribute.getName() + " not found.");
            }
            catch (ClassCastException e)
            {
            throw new InvalidAttributeValueException("Invalid attribute type " + attribute.getValue().getClass().getName());
            }
            }


            // setAttributes implementation

            public AttributeList setAttributes (AttributeList list)
            {
            System.out.println ("setAttributes");
            if (list == null)
            throw new IllegalArgumentException("null list");

            AttributeList results = new AttributeList();
            Iterator it = list.iterator();

            while (it.hasNext())
            {
            try
            {
            Attribute attr = (Attribute)it.next();
            setAttribute(attr);
            results.add(attr);
            }
            catch (JMException ignored)
            {
            // if unable to set the attribute, skip it
            }
            }
            return results;
            }


            // invoke implementation

            public Object invoke(String actionName,
            Object[] params,
            String[] signature) throws MBeanException, ReflectionException {
            System.out.println ("invoke");
            if (actionName == null || actionName.equals(""))
            throw new IllegalArgumentException("no operation");

            // map operation names to methods
            if (actionName.equals(START_PULSE))
            {
            startPulse();
            return null;
            }
            else if (actionName.equals(STOP_PULSE))
            {
            stopPulse ();
            return null;
            }
            else
            throw new UnsupportedOperationException("unknown operation " + actionName);
            }


            // getMBeanInfo implementation
            public MBeanInfo getMBeanInfo()
            {
            return info;
            }

            public static /*MBeanInfo*/ ModelMBeanInfo createMBeanInfo()
            {
            System.out.println ("getMBeanInfo");
            //final boolean IS_READABLE = true;
            //final boolean IS_WRITABLE = true;
            //final boolean IS_IS = true;

            // MBean class and description
            //String className = getClass().getName();
            String className = PulsarStandard.class.getName();
            String description =
            "User resource with model management interface";

            // build 'RoomName' read-write attribute
            /*Descriptor descr_my = new DescriptorSupport();
            descr_my.setField(PERSIST_POLICY, "OnUpdate");
            descr_my.setField(PERSIST_LOCATION, "c:\\aa");
            descr_my.setField(PERSIST_NAME, "storage.txt");
            System.out.println ("Valid " + descr_my.isValid());*/

            // meta data for 'PULSE_PERIOD' attribute.
            ModelMBeanAttributeInfo mPulsePeriod = new ModelMBeanAttributeInfo(
            PULSE_PERIOD, // name
            int.class.getName(), // type
            "Pulse Period", // description
            IS_READABLE, IS_WRITABLE, !IS_IS//, // access
            //descr_my
            );

            // meta data for 'IF_STARTED' attribute.
            ModelMBeanAttributeInfo mStarted = new ModelMBeanAttributeInfo(
            IF_STARTED, // name
            boolean.class.getName(), // type
            "If the Pulser has Started", // description
            IS_READABLE, !IS_WRITABLE, !IS_IS // access
            );

            // meta data for 'startPulse' operation
            ModelMBeanOperationInfo startPulse = new ModelMBeanOperationInfo(
            START_PULSE, // name
            "Start the pulsar", // description
            null, // signature
            void.class.getName(), // return type
            MBeanOperationInfo.ACTION // impact
            );

            // meta data for 'stopPulse' operation
            ModelMBeanOperationInfo stopPulse = new ModelMBeanOperationInfo(
            STOP_PULSE, // name
            "Stop the pulsar", // description
            null, // signature
            void.class.getName(), // return type
            MBeanOperationInfo.ACTION // impact
            );

            // mbean constructors
            ModelMBeanConstructorInfo defaultConstructor =
            new ModelMBeanConstructorInfo(
            "Default Constructor",
            "Creates a new Pulsar", null
            );

            // attribute, constructor and operation lists
            ModelMBeanAttributeInfo[] attributes = new ModelMBeanAttributeInfo[] {mPulsePeriod, mStarted};

            ModelMBeanConstructorInfo[] constructors = new ModelMBeanConstructorInfo[] {defaultConstructor};

            ModelMBeanOperationInfo[] operations = new ModelMBeanOperationInfo[] {startPulse, stopPulse};

            // return the MBeanInfo
            return new ModelMBeanInfoSupport (className, description, attributes, constructors, operations, null);
            }

            // RW attributes
            /*
            public int getPulsePeriodInMills ()
            {
            return mPulsePeriod;
            }

            public void setPulsePeriodInMills (int pPulsePeriod)
            {
            mPulsePeriod = pPulsePeriod ;
            }

            public boolean getStarted ()
            {
            return mStarted;
            }
            */

            public void startPulse ()
            {
            System.out.println ("startPulse");
            mThread.start ();
            try
            {
            mSNC.connect();
            mStarted = true ;
            }
            catch (Exception e)
            {
            mStarted = false ;
            }
            }

            public void stopPulse ()
            {
            System.out.println ("stopPulse");
            mThread.stop ();
            mSNC.disconnect();
            mStarted = false ;
            }

            public void run ()
            {
            System.out.println ("run");
            try
            {
            while (true)
            {
            mThread.sleep (mPulsePeriod);
            if (mStarted)
            {
            System.out.println("Pulsing");
            mSNC.sendPulse();
            }
            }
            }
            catch (Exception ex)
            {
            ex.printStackTrace();
            }
            }
            }

            //////////////////////////////////////////////////////////////////////////////////////
            //////////////////////////////////////////////////////////////////////////////////////
            //////////////////////////////////////////////////////////////////////////////////////
            --------------- end ----------------------------


            • 3. Re: What is wrong with ModelMBean and what is the difference
              Alexander Rabinowitz Newbie

              Actually, the type of Exception depends on what I use:

              If I use the following (the constructors do not use the descriptor):
              /*Descriptor descr_my = new DescriptorSupport();
              descr_my.setField(PERSIST_POLICY, "OnUpdate");
              descr_my.setField(PERSIST_LOCATION, "c:\\aa");
              descr_my.setField(PERSIST_NAME, "storage.txt");
              System.out.println ("Valid " + descr_my.isValid());
              System.out.println ("Name: " + void.class.getName());*/

              // meta data for 'PULSE_PERIOD' attribute.
              ModelMBeanAttributeInfo mPulsePeriod = new ModelMBeanAttributeInfo(
              PULSE_PERIOD, // name
              int.class.getName(), // type
              "Pulse Period", // description
              ModelBase.IS_READABLE, ModelBase.IS_WRITABLE, !ModelBase.IS_IS//, // access
              //descr_my
              );

              // meta data for 'IF_STARTED' attribute.
              ModelMBeanAttributeInfo mStarted = new ModelMBeanAttributeInfo(
              IF_STARTED, // name
              boolean.class.getName(), // type
              "If the Pulser has Started", // description
              ModelBase.IS_READABLE, !ModelBase.IS_WRITABLE, !ModelBase.IS_IS // access
              );

              // meta data for 'startPulse' operation
              ModelMBeanOperationInfo startPulse = new ModelMBeanOperationInfo(
              START_PULSE, // name
              "Start the pulsar", // description
              null, // signature
              void.class.getName(), // return type
              MBeanOperationInfo.ACTION//, // impact
              //descr_my
              );

              // meta data for 'stopPulse' operation
              ModelMBeanOperationInfo stopPulse = new ModelMBeanOperationInfo(
              STOP_PULSE, // name
              "Stop the pulsar", // description
              null, // signature
              void.class.getName(), // return type
              MBeanOperationInfo.ACTION // impact
              );

              Then I have
              MBeanException: preRegister() failed
              [ObjectName='DefaultDomain:type=com.peerdirect.rmapplications.master.jmx.PulsarStandard',Class=com.peerdirect.rmapplications.master.jmx.PulsarStandard
              (com.peerdirect.rmapplications.master.jmx.PulsarStandard@5bdc50)]
              Cause: java.lang.NullPointerException
              at
              org.jboss.mx.server.registry.BasicMBeanRegistry.registerMBean(BasicMBeanRegistry.java:187)
              at org.jboss.mx.server.MBeanServerImpl.registerMBean(MBeanServerImpl.java:975)
              at org.jboss.mx.server.MBeanServerImpl.registerMBean(MBeanServerImpl.java:302)
              at com.peerdirect.rmapplications.agent.BaseAgent.(BaseAgent.java:67)
              at com.peerdirect.rmapplications.agent.MasterAgent.(MasterAgent.java:5)
              at com.peerdirect.rmapplications.agent.MasterAgent.main(MasterAgent.java:15)

              But if I use another constructor, which uses descriptor:

              // meta data for 'startPulse' operation
              ModelMBeanOperationInfo startPulse = new ModelMBeanOperationInfo(
              START_PULSE, // name
              "Start the pulsar", // description
              null, // signature
              void.class.getName(), // return type
              MBeanOperationInfo.ACTION//, // impact
              descr_my
              );

              Then I have the following:

              MBeanException: preRegister() failed [ObjectName='DefaultDomain:type=com.peerdir
              ect.rmapplications.master.jmx.PulsarStandard',
              Class=com.peerdirect.rmapplications.master.jmx.PulsarStandard (com.peerdirect.rmapplications.master.jmx.PulsarStandard@3020ad)]
              Cause: ReflectionException: null
              Cause: javax.management.IntrospectionException: no method found for operation: startPulse
              at org.jboss.mx.server.registry.BasicMBeanRegistry.registerMBean(BasicMBeanRegistry.java:187)
              at org.jboss.mx.server.MBeanServerImpl.registerMBean(MBeanServerImpl.java:975)
              at org.jboss.mx.server.MBeanServerImpl.registerMBean(MBeanServerImpl.java:302)
              at com.peerdirect.rmapplications.agent.BaseAgent.(BaseAgent.java:67)
              at com.peerdirect.rmapplications.agent.MasterAgent.(MasterAgent.java:5)
              at com.peerdirect.rmapplications.agent.MasterAgent.main(MasterAgent.java:15)

              And that is all after the changes I made for the constructor.

              • 4. Re: What is wrong with ModelMBean and what is the difference
                Adrian Brock Master

                Change the following

                -setManagedResource (new Object (), OBJECT_REF);
                +setManagedResource (this, OBJECT_REF);

                Regards,
                Adrian