JMX 

 

The JMX technology provides a simple, standard way of managing resources such as applications 

 

Using the JMX technology, a given resource is instrumented by one or more Java objects known as Managed Beans, or MBeans. These MBeans are registered in a core-managed object server, known as an MBean server. The MBean server acts as a management agent and can run on most devices that have been enabled for the Java programming language.

 

# * Server.java: creates an MBeanServer, 

#                registers a SimpleStandard MBean on the local MBeanServer,

#                registers a SimpleDynamic MBean on the local MBeanServer,

#                performs local operations on both MBeans,

#                creates and starts an RMI connector server (JRMP).

# * Client.java: creates an RMI connector (JRMP), 

#                registers a SimpleStandard MBean on the remote MBeanServer,

#                registers a SimpleDynamic MBean on the remote MBeanServer,

#                performs remote operations on both MBeans,

#                closes the RMI connector.

# * ClientListener.java: implements a generic notification listener. 

# * SimpleStandard.java: implements the Simple standard MBean. 

# * SimpleStandardMBean.java: the management interface exposed 

#                             by the Simple standard MBean.

# * SimpleDynamic.java: implements the Simple dynamic MBean. 

 

 

public class Server {

 

    public static void main(String[] args) {

        try {

            // Instantiate the MBean server

            //

            echo("\n>>> Create the MBean server");

            MBeanServer mbs = MBeanServerFactory.createMBeanServer();

           waitForEnterPressed();

 

           // Get default domain

           //

            echo("\n>>> Get the MBean server's default domain");

           String domain = mbs.getDefaultDomain();

           echo("\tDefault Domain = " + domain);

           waitForEnterPressed();

 

           // Create and register the SimpleStandard MBean

           //

           String mbeanClassName = "SimpleStandard";

           String mbeanObjectNameStr =

                domain + ":type=" + mbeanClassName + ",name=1";

           ObjectName mbeanObjectName =

                createSimpleMBean(mbs, mbeanClassName, mbeanObjectNameStr);

           waitForEnterPressed();

 

           // Get and display the management information exposed by the

           // SimpleStandard MBean

           //

           printMBeanInfo(mbs, mbeanObjectName, mbeanClassName);

           waitForEnterPressed();

 

           // Manage the SimpleStandard MBean

           //

           manageSimpleMBean(mbs, mbeanObjectName, mbeanClassName);

           waitForEnterPressed();

 

           // Create and register the SimpleDynamic MBean

           //

           mbeanClassName = "SimpleDynamic";

           mbeanObjectNameStr =

                domain + ":type=" + mbeanClassName + ",name=1";

           mbeanObjectName =

                createSimpleMBean(mbs, mbeanClassName, mbeanObjectNameStr);

           waitForEnterPressed();

 

           // Get and display the management information exposed by the

           // SimpleDynamic MBean

           //

           printMBeanInfo(mbs, mbeanObjectName, mbeanClassName);

           waitForEnterPressed();

 

           // Manage the SimpleDynamic MBean

           //

           manageSimpleMBean(mbs, mbeanObjectName, mbeanClassName);

           waitForEnterPressed();

 

            // Create an RMI connector server

            //

            echo("\nCreate an RMI connector server");

            JMXServiceURL url = new JMXServiceURL(

                     "service:jmx:rmi:///jndi/rmi://localhost:9999/server");

            JMXConnectorServer cs =

                JMXConnectorServerFactory.newJMXConnectorServer(url, null, mbs);

 

            // Start the RMI connector server

            //

            echo("\nStart the RMI connector server");

            cs.start();

            echo("\nThe RMI connector server successfully started");

           echo("and is ready to handle incoming connections");

            echo("\nStart the client on a different window and");

           echo("press <Enter> once the client has finished");

           waitForEnterPressed();

 

           // Stop the RMI connector server

           //

            echo("\nStop the RMI connector server");

           cs.stop();

            System.out.println("\nBye! Bye!");

        } catch (Exception e) {

            e.printStackTrace();

        }

    }

 

    private static ObjectName createSimpleMBean(MBeanServer mbs,

                                                String mbeanClassName,

                                                String mbeanObjectNameStr) {

        echo("\n>>> Create the " + mbeanClassName +

            " MBean within the MBeanServer");

        echo("\tObjectName = " + mbeanObjectNameStr);

        try {

           ObjectName mbeanObjectName =

                ObjectName.getInstance(mbeanObjectNameStr);

           mbs.createMBean(mbeanClassName, mbeanObjectName);

           return mbeanObjectName;

        } catch (Exception e) {

           echo("\t!!! Could not create the " + mbeanClassName + " MBean !!!");

           e.printStackTrace();

           echo("\nEXITING...\n");

           System.exit(1);

        }

        return null;

    }

 

    private static void printMBeanInfo(MBeanServer mbs,

                                      ObjectName mbeanObjectName,

                                      String mbeanClassName) {

        echo("\n>>> Retrieve the management information for the " +

            mbeanClassName);

        echo("    MBean using the getMBeanInfo() method of the MBeanServer");

        MBeanInfo info = null;

        try {

           info = mbs.getMBeanInfo(mbeanObjectName);

        } catch (Exception e) {

           echo("\t!!! Could not get MBeanInfo object for " +

                mbeanClassName +" !!!");

           e.printStackTrace();

           return;

        }

        echo("\nCLASSNAME: \t" + info.getClassName());

        echo("\nDESCRIPTION: \t" + info.getDescription());

        echo("\nATTRIBUTES");

        MBeanAttributeInfo[] attrInfo = info.getAttributes();

        if (attrInfo.length > 0) {

           for (int i = 0; i < attrInfo.length; i++) {

                echo(" ** NAME: \t" + attrInfo[i].getName());

                echo("    DESCR: \t" + attrInfo[i].getDescription());

                echo("    TYPE: \t" + attrInfo[i].getType() +

                    "\tREAD: "+ attrInfo[i].isReadable() +

                    "\tWRITE: "+ attrInfo[i].isWritable());

           }

        } else echo(" ** No attributes **");

        echo("\nCONSTRUCTORS");

        MBeanConstructorInfo[] constrInfo = info.getConstructors();

        for (int i=0; i<constrInfo.length; i++) {

           echo(" ** NAME: \t" + constrInfo[i].getName());

           echo("    DESCR: \t" + constrInfo[i].getDescription());

           echo("    PARAM: \t" + constrInfo[i].getSignature().length +

                " parameter(s)");

        }

        echo("\nOPERATIONS");

        MBeanOperationInfo[] opInfo = info.getOperations();

        if (opInfo.length > 0) {

           for (int i = 0; i < opInfo.length; i++) {

                echo(" ** NAME: \t" + opInfo[i].getName());

                echo("    DESCR: \t" + opInfo[i].getDescription());

                echo("    PARAM: \t" + opInfo[i].getSignature().length +

                    " parameter(s)");

           }

        } else echo(" ** No operations ** ");

        echo("\nNOTIFICATIONS");

        MBeanNotificationInfo[] notifInfo = info.getNotifications();

        if (notifInfo.length > 0) {

           for (int i = 0; i < notifInfo.length; i++) {

                echo(" ** NAME: \t" + notifInfo[i].getName());

                echo("    DESCR: \t" + notifInfo[i].getDescription());

                String notifTypes[] = notifInfo[i].getNotifTypes();

                for (int j = 0; j < notifTypes.length; j++) {

                   echo("    TYPE: \t" + notifTypes[j]);

                }

           }

        } else echo(" ** No notifications **");

    }

 

    private static void manageSimpleMBean(MBeanServer mbs,

                                         ObjectName mbeanObjectName,

                                         String mbeanClassName) {

 

        echo("\n>>> Manage the " + mbeanClassName +

            " MBean using its attributes ");

        echo("    and operations exposed for management");

 

        try {

           // Get attribute values

           printSimpleAttributes(mbs, mbeanObjectName);

 

           // Change State attribute

           echo("\n    Setting State attribute to value \"new state\"...");

           Attribute stateAttribute = new Attribute("State","new state");

           mbs.setAttribute(mbeanObjectName, stateAttribute);

           // Get attribute values

           printSimpleAttributes(mbs, mbeanObjectName);

 

           // Invoking reset operation

           echo("\n    Invoking reset operation...");

           mbs.invoke(mbeanObjectName, "reset", null, null);

 

           // Get attribute values

           printSimpleAttributes(mbs, mbeanObjectName);

        } catch (Exception e) {

           e.printStackTrace();

        }

    }

 

    private static void printSimpleAttributes(MBeanServer mbs,

                                             ObjectName mbeanObjectName) {

        try {

           echo("\n    Getting attribute values:");

           String State = (String) mbs.getAttribute(mbeanObjectName, "State");

           Integer NbChanges =

                (Integer) mbs.getAttribute(mbeanObjectName,"NbChanges");

           echo("\tState     = \"" + State + "\"");

           echo("\tNbChanges = " + NbChanges);

        } catch (Exception e) {

           echo("\t!!! Could not read attributes !!!");

           e.printStackTrace();

        }

    }

 

    private static void echo(String msg) {

        System.out.println(msg);

    }

 

    private static void sleep(int millis) {

        try {

           Thread.sleep(millis);

        } catch (InterruptedException e) {

           e.printStackTrace();

        }

    }

 

    private static void waitForEnterPressed() {

        try {

           echo("\nPress <Enter> to continue...");

           System.in.read();

        } catch (IOException e) {

           e.printStackTrace();

        }

    }

 

 

 

 

public class Client {

 

    public static void main(String[] args) {

        try {

            // Create an RMI connector client and

            // connect it to the RMI connector server

            //

            echo("\nCreate an RMI connector client and " +

                "connect it to the RMI connector server");

            JMXServiceURL url = new JMXServiceURL(

                     "service:jmx:rmi:///jndi/rmi://localhost:9999/server");

            JMXConnector jmxc = JMXConnectorFactory.connect(url, null);

 

           // Create listener

           //

            ClientListener listener = new ClientListener();

 

            // Get an MBeanServerConnection

            //

            echo("\nGet an MBeanServerConnection");

            MBeanServerConnection mbsc = jmxc.getMBeanServerConnection();

           waitForEnterPressed();

 

            // Get domains from MBeanServer

            //

            echo("\nDomains:");

            String domains[] = mbsc.getDomains();

            for (int i = 0; i < domains.length; i++) {

                echo("\tDomain[" + i + "] = " + domains[i]);

            }

           waitForEnterPressed();

 

           // Get MBeanServer's default domain

           //

           String domain = mbsc.getDefaultDomain();

 

            // Create SimpleStandard MBean

            //

            ObjectName stdMBeanName =

                new ObjectName(domain +":type=SimpleStandard,name=2");

            echo("\nCreate SimpleStandard MBean...");

            mbsc.createMBean("SimpleStandard", stdMBeanName, null, null);

           waitForEnterPressed();

 

            // Create SimpleDynamic MBean

            //

            ObjectName dynMBeanName =

                new ObjectName(domain +":type=SimpleDynamic,name=2");

            echo("\nCreate SimpleDynamic MBean...");

            mbsc.createMBean("SimpleDynamic", dynMBeanName, null, null);

           waitForEnterPressed();

 

            // Get MBean count

            //

            echo("\nMBean count = " + mbsc.getMBeanCount());

 

           // Query MBean names

           //

            echo("\nQuery MBeanServer MBeans:");

           Set names = mbsc.queryNames(null, null);

           for (Iterator i = names.iterator(); i.hasNext(); ) {

                echo("\tObjectName = " + (ObjectName) i.next());

           }

           waitForEnterPressed();

 

           // -------------------------------

           // Manage the SimpleStandard MBean

           // -------------------------------

            echo("\n>>> Perform operations on SimpleStandard MBean <<<");

 

            // Get State attribute in SimpleStandard MBean

            //

            echo("\nState = " + mbsc.getAttribute(stdMBeanName, "State"));

 

            // Set State attribute in SimpleStandard MBean

            //

            mbsc.setAttribute(stdMBeanName,

                              new Attribute("State", "changed state"));

 

            // Get State attribute in SimpleStandard MBean

           //

           // Another way of interacting with a given MBean is through a

           // dedicated proxy instead of going directly through the MBean

           // server connection

           //

           SimpleStandardMBean proxy = JMX.newMBeanProxy(

                    mbsc, stdMBeanName, SimpleStandardMBean.class, true);

            echo("\nState = " + proxy.getState());

 

            // Add notification listener on SimpleStandard MBean

            //

            echo("\nAdd notification listener...");

            mbsc.addNotificationListener(stdMBeanName, listener, null, null);

 

            // Invoke "reset" in SimpleStandard MBean

            //

            // Calling "reset" makes the SimpleStandard MBean emit a

            // notification that will be received by the registered

            // ClientListener.

            //

            echo("\nInvoke reset() in SimpleStandard MBean...");

            mbsc.invoke(stdMBeanName, "reset", null, null);

 

            // Sleep for 2 seconds in order to have time to receive the

            // notification before removing the notification listener.

            //

            echo("\nWaiting for notification...");

            sleep(2000);

 

            // Remove notification listener on SimpleStandard MBean

            //

            echo("\nRemove notification listener...");

            mbsc.removeNotificationListener(stdMBeanName, listener);

 

            // Unregister SimpleStandard MBean

            //

            echo("\nUnregister SimpleStandard MBean...");

            mbsc.unregisterMBean(stdMBeanName);

           waitForEnterPressed();

 

           // ------------------------------

           // Manage the SimpleDynamic MBean

           // ------------------------------

            echo("\n>>> Perform operations on SimpleDynamic MBean <<<");

 

            // Get State attribute in SimpleDynamic MBean

            //

            echo("\nState = " + mbsc.getAttribute(dynMBeanName, "State"));

 

            // Set State attribute in SimpleDynamic MBean

            //

            mbsc.setAttribute(dynMBeanName,

                              new Attribute("State", "changed state"));

 

            // Get State attribute in SimpleDynamic MBean

            //

            echo("\nState = " +

                               mbsc.getAttribute(dynMBeanName, "State"));

 

            // Add notification listener on SimpleDynamic MBean

            //

            echo("\nAdd notification listener...");

            mbsc.addNotificationListener(dynMBeanName, listener, null, null);

 

            // Invoke "reset" in SimpleDynamic MBean

            //

            // Calling "reset" makes the SimpleDynamic MBean emit a

            // notification that will be received by the registered

            // ClientListener.

            //

            echo("\nInvoke reset() in SimpleDynamic MBean...");

            mbsc.invoke(dynMBeanName, "reset", null, null);

 

            // Sleep for 2 seconds in order to have time to receive the

            // notification before removing the notification listener.

            //

            echo("\nWaiting for notification...");

            sleep(2000);

 

            // Remove notification listener on SimpleDynamic MBean

            //

            echo("\nRemove notification listener...");

            mbsc.removeNotificationListener(dynMBeanName, listener);

 

            // Unregister SimpleDynamic MBean

            //

            echo("\nUnregister SimpleDynamic MBean...");

            mbsc.unregisterMBean(dynMBeanName);

           waitForEnterPressed();

 

            // Close MBeanServer connection

            //

            echo("\nClose the connection to the server");

            jmxc.close();

            echo("\nBye! Bye!");

        } catch (Exception e) {

            e.printStackTrace();

        }

    }

 

    private static void echo(String msg) {

        System.out.println(msg);

    }

 

    private static void sleep(int millis) {

        try {

           Thread.sleep(millis);

        } catch (InterruptedException e) {

           e.printStackTrace();

        }

    }

 

    private static void waitForEnterPressed() {

        try {

           echo("\nPress <Enter> to continue...");

           System.in.read();

        } catch (IOException e) {

           e.printStackTrace();

        }

    }

 

 

 

 

public class ClientListener implements NotificationListener {

    public void handleNotification(Notification notification, Object handback) {

        System.out.println("\nReceived notification: " + notification);

    }

 

 

 

public class SimpleDynamic

    extends NotificationBroadcasterSupport

    implements DynamicMBean {

 

    /*

     * -----------------------------------------------------

     * CONSTRUCTORS

     * -----------------------------------------------------

     */

 

    public SimpleDynamic() {

        // Build the management information to be exposed by the dynamic MBean

        //

        buildDynamicMBeanInfo();

    }

 

    /*

     * -----------------------------------------------------

     * IMPLEMENTATION OF THE DynamicMBean INTERFACE

     * -----------------------------------------------------

     */

 

    /**

     * Allows the value of the specified attribute of the Dynamic MBean to be

     * obtained.

     */

    public Object getAttribute(String attribute_name)

        throws AttributeNotFoundException,

               MBeanException,

               ReflectionException {

 

        // Check attribute_name is not null to avoid NullPointerException

        // later on

        //

        if (attribute_name == null) {

            throw new RuntimeOperationsException(

                  new IllegalArgumentException("Attribute name cannot be null"),

                  "Cannot invoke a getter of " + dClassName +

                  " with null attribute name");

        }

        // Check for a recognized attribute_name and call the corresponding

        // getter

        //

        if (attribute_name.equals("State")) {

            return getState();

        }

        if (attribute_name.equals("NbChanges")) {

            return getNbChanges();

        }

        // If attribute_name has not been recognized throw an

        // AttributeNotFoundException

        //

        throw new AttributeNotFoundException("Cannot find " +

                                             attribute_name +

                                             " attribute in " +

                                             dClassName);

    }

 

    /**

     * Sets the value of the specified attribute of the Dynamic MBean.

     */

    public void setAttribute(Attribute attribute)

        throws AttributeNotFoundException,

               InvalidAttributeValueException,

               MBeanException,

               ReflectionException {

 

        // Check attribute is not null to avoid NullPointerException later on

        //

        if (attribute == null) {

            throw new RuntimeOperationsException(

                  new IllegalArgumentException("Attribute cannot be null"),

                  "Cannot invoke a setter of " + dClassName +

                  " with null attribute");

        }

        String name = attribute.getName();

        Object value = attribute.getValue();

        if (name == null) {

            throw new RuntimeOperationsException(

                  new IllegalArgumentException("Attribute name cannot be null"),

                  "Cannot invoke the setter of " + dClassName +

                  " with null attribute name");

        }

        // Check for a recognized attribute name and call the corresponding

        // setter

        //

        if (name.equals("State")) {

            // if null value, try and see if the setter returns any exception

            if (value == null) {

                try {

                    setState( null );

                } catch (Exception e) {

                    throw new InvalidAttributeValueException(

                              "Cannot set attribute " + name + " to null");

                }

            }

            // if non null value, make sure it is assignable to the attribute

            else {

                try {

                    if (Class.forName("java.lang.String").isAssignableFrom(

                                                          value.getClass())) {

                        setState((String) value);

                    } else {

                        throw new InvalidAttributeValueException(

                                  "Cannot set attribute " + name + " to a " +

                                  value.getClass().getName() +

                                  " object, String expected");

                    }

                } catch (ClassNotFoundException e) {

                    e.printStackTrace();

                }

            }

        }

        // recognize an attempt to set "NbChanges" attribute (read-only):

        else if (name.equals("NbChanges")) {

            throw new AttributeNotFoundException(

                  "Cannot set attribute " + name + " because it is read-only");

        }

        // unrecognized attribute name:

        else {

            throw new AttributeNotFoundException("Attribute " + name +

                                                 " not found in " +

                                                 this.getClass().getName());

        }

    }

 

    /**

     * Enables the to get the values of several attributes of the Dynamic MBean.

     */

    public AttributeList getAttributes(String[] attributeNames) {

 

        // Check attributeNames is not null to avoid NullPointerException

        // later on

        //

        if (attributeNames == null) {

            throw new RuntimeOperationsException(

                new IllegalArgumentException("attributeNames[] cannot be null"),

                "Cannot invoke a getter of " + dClassName);

        }

        AttributeList resultList = new AttributeList();

 

        // If attributeNames is empty, return an empty result list

        //

        if (attributeNames.length == 0)

            return resultList;

       

        // Build the result attribute list

        //

        for (int i = 0 ; i < attributeNames.length ; i++) {

            try {        

                Object value = getAttribute((String) attributeNames[i]);    

                resultList.add(new Attribute(attributeNames[i],value));

            } catch (Exception e) {

                e.printStackTrace();

            }

        }

        return resultList;

    }

 

    /**

     * Sets the values of several attributes of the Dynamic MBean, and returns

     * the list of attributes that have been set.

     */

    public AttributeList setAttributes(AttributeList attributes) {

 

        // Check attributes is not null to avoid NullPointerException later on

        //

        if (attributes == null) {

            throw new RuntimeOperationsException(

                      new IllegalArgumentException(

                                 "AttributeList attributes cannot be null"),

                      "Cannot invoke a setter of " + dClassName);

        }

        AttributeList resultList = new AttributeList();

 

        // If attributeNames is empty, nothing more to do

        //

        if (attributes.isEmpty())

            return resultList;

 

        // For each attribute, try to set it and add to the result list if

        // successfull

        //

        for (Iterator i = attributes.iterator(); i.hasNext();) {

            Attribute attr = (Attribute) i.next();

            try {

                setAttribute(attr);

                String name = attr.getName();

                Object value = getAttribute(name);

                resultList.add(new Attribute(name,value));

            } catch(Exception e) {

                e.printStackTrace();

            }

        }

        return resultList;

    }

 

    /**

     * Allows an operation to be invoked on the Dynamic MBean.

     */

    public Object invoke(String operationName,

                         Object params[],

                         String signature[])

        throws MBeanException, ReflectionException {

        // Check operationName is not null to avoid NullPointerException

        // later on

        //

        if (operationName == null) {

            throw new RuntimeOperationsException(

                 new IllegalArgumentException("Operation name cannot be null"),

                 "Cannot invoke a null operation in " + dClassName);

        }

        // Check for a recognized operation name and call the corresponding

        // operation

        //

        if (operationName.equals("reset")) {

            reset();

            return null;

        } else {

            // Unrecognized operation name

            //

            throw new ReflectionException(

                                new NoSuchMethodException(operationName),

                                "Cannot find the operation " + operationName +

                                " in " + dClassName);

        }

    }

 

    /**

     * This method provides the exposed attributes and operations of the

     * Dynamic MBean. It provides this information using an MBeanInfo object.

     */

    public MBeanInfo getMBeanInfo() {

 

        // Return the information we want to expose for management:

        // the dMBeanInfo private field has been built at instanciation time

        //

        return dMBeanInfo;

    }

 

    /*

     * -----------------------------------------------------

     * OTHER PUBLIC METHODS

     * -----------------------------------------------------

     */

 

    /**

     * Getter: get the "State" attribute of the "SimpleDynamic" dynamic MBean.

     */

    public String getState() {

        return state;

    }

 

    /**

     * Setter: set the "State" attribute of the "SimpleDynamic" dynamic MBean.

     */

    public void setState(String s) {

        state = s;

        nbChanges++;

    }

 

    /**

     * Getter: get the "NbChanges" attribute of the "SimpleDynamic" dynamic

     * MBean.

     */

    public Integer getNbChanges() {

        return new Integer(nbChanges);

    }

 

    /**

     * Operation: reset to their initial values the "State" and "NbChanges"

     * attributes of the "SimpleDynamic" dynamic MBean.

     */

    public void reset() {

        AttributeChangeNotification acn =

            new AttributeChangeNotification(this,

                                            0,

                                            0,

                                            "NbChanges reset",

                                            "NbChanges",

                                            "Integer",

                                            new Integer(nbChanges),

                                            new Integer(0));

        state = "initial state";

        nbChanges = 0;

        nbResets++;

        sendNotification(acn);

    }

 

    /**

     * Return the "NbResets" property.

     * This method is not a Getter in the JMX sense because

     * it is not returned by the getMBeanInfo() method.

     */

    public Integer getNbResets() {

        return new Integer(nbResets);

    }

 

    /*

     * -----------------------------------------------------

     * PRIVATE METHODS

     * -----------------------------------------------------

     */

 

    /**

     * Build the private dMBeanInfo field,

     * which represents the management interface exposed by the MBean,

     * that is, the set of attributes, constructors, operations and

     * notifications which are available for management.

     *

     * A reference to the dMBeanInfo object is returned by the getMBeanInfo()

     * method of the DynamicMBean interface. Note that, once constructed, an

     * MBeanInfo object is immutable.

     */

    private void buildDynamicMBeanInfo() {

 

        dAttributes[0] =

            new MBeanAttributeInfo("State",

                                   "java.lang.String",

                                   "State string.",

                                   true,

                                   true,

                                   false);

        dAttributes[1] =

            new MBeanAttributeInfo("NbChanges",

                                   "java.lang.Integer",

                                   "Number of times the " +

                                   "State string has been changed.",

                                   true,

                                   false,

                                   false);

 

        Constructor[] constructors = this.getClass().getConstructors();

        dConstructors[0] =

            new MBeanConstructorInfo("Constructs a " +

                                     "SimpleDynamic object",

                                     constructors[0]);

 

        MBeanParameterInfo[] params = null;

        dOperations[0] =

            new MBeanOperationInfo("reset",

                                   "reset State and NbChanges " +

                                   "attributes to their initial values",

                                   params ,

                                   "void",

                                   MBeanOperationInfo.ACTION);

 

        dNotifications[0] =

            new MBeanNotificationInfo(

            new String[] { AttributeChangeNotification.ATTRIBUTE_CHANGE },

            AttributeChangeNotification.class.getName(),

            "This notification is emitted when the reset() method is called.");

 

        dMBeanInfo = new MBeanInfo(dClassName,

                                   dDescription,

                                   dAttributes,

                                   dConstructors,

                                   dOperations,

                                   dNotifications);

    }

    /*

     * -----------------------------------------------------

     * PRIVATE VARIABLES

     * -----------------------------------------------------

     */

 

    private String state = "initial state";

    private int nbChanges = 0;

    private int nbResets = 0;

 

    private String dClassName = this.getClass().getName();

    private String dDescription = "Simple implementation of a dynamic MBean.";

 

    private MBeanAttributeInfo[] dAttributes =

        new MBeanAttributeInfo[2];

    private MBeanConstructorInfo[] dConstructors =

        new MBeanConstructorInfo[1];

    private MBeanNotificationInfo[] dNotifications =

        new MBeanNotificationInfo[1];

    private MBeanOperationInfo[] dOperations =

        new MBeanOperationInfo[1];

    private MBeanInfo dMBeanInfo = null;

 

public interface SimpleStandardMBean {

 

    /**

     * Getter: set the "State" attribute of the "SimpleStandard" standard

     * MBean.

     *

     * @return the current value of the "State" attribute.

     */

    public String getState();

 

    /**

     * Setter: set the "State" attribute of the "SimpleStandard" standard

     * MBean.

     *

     * @param <VAR>s</VAR> the new value of the "State" attribute.

     */

    public void setState(String s);

 

    /**

     * Getter: get the "NbChanges" attribute of the "SimpleStandard" standard

     * MBean.

     *

     * @return the current value of the "NbChanges" attribute.

     */

    public int getNbChanges();

 

    /**

     * Operation: reset to their initial values the "State" and "NbChanges"

     * attributes of the "SimpleStandard" standard MBean.

     */

    public void reset();

 

 

 

public class SimpleStandard

    extends NotificationBroadcasterSupport

    implements SimpleStandardMBean {

 

    /*

     * -----------------------------------------------------

     * CONSTRUCTORS

     * -----------------------------------------------------

     */

 

    /* "SimpleStandard" does not provide any specific constructors.

     * However, "SimpleStandard" is JMX compliant with regards to

     * contructors because the default contructor SimpleStandard()

     * provided by the Java compiler is public.

     */

 

    /*

     * -----------------------------------------------------

     * IMPLEMENTATION OF THE SimpleStandardMBean INTERFACE

     * -----------------------------------------------------

     */

 

    /**

     * Getter: get the "State" attribute of the "SimpleStandard" standard MBean.

     *

     * @return the current value of the "State" attribute.

     */

    public String getState() {

        return state;

    }

 

    /**

     * Setter: set the "State" attribute of the "SimpleStandard" standard MBean.

     *

     * @param <VAR>s</VAR> the new value of the "State" attribute.

     */

    public void setState(String s) {

        state = s;

        nbChanges++;

    }

 

    /**

     * Getter: get the "NbChanges" attribute of the "SimpleStandard" standard

     * MBean.

     *

     * @return the current value of the "NbChanges" attribute.

     */

    public int getNbChanges() {

        return nbChanges;

    }

 

    /**

     * Operation: reset to their initial values the "State" and "NbChanges"

     * attributes of the "SimpleStandard" standard MBean.

     */

    public void reset() {

        AttributeChangeNotification acn =

           new AttributeChangeNotification(this,

                                           0,

                                           0,

                                           "NbChanges reset",

                                           "NbChanges",

                                           "Integer",

                                           new Integer(nbChanges),

                                           new Integer(0));

        state = "initial state";

        nbChanges = 0;

        nbResets++;

        sendNotification(acn);

    }

 

    /*

     * -----------------------------------------------------

     * METHOD NOT EXPOSED FOR MANAGEMENT BY A JMX AGENT

     * -----------------------------------------------------

     */

 

    /**

     * Return the "NbResets" property.

     * This method is not a Getter in the JMX sense because it

     * is not exposed in the "SimpleStandardMBean" interface.

     *

     * @return the current value of the "NbResets" property.

     */

    public int getNbResets() {

        return nbResets;

    }

 

    /**

     * Returns an array indicating, for each notification this MBean

     * may send, the name of the Java class of the notification and

     * the notification type.</p>

     *

     * @return the array of possible notifications.

     */

    public MBeanNotificationInfo[] getNotificationInfo() {

        return new MBeanNotificationInfo[] {

           new MBeanNotificationInfo(

           new String[] { AttributeChangeNotification.ATTRIBUTE_CHANGE },

           AttributeChangeNotification.class.getName(),

           "This notification is emitted when the reset() method is called.")

        };

    }

 

    /*

     * -----------------------------------------------------

     * ATTRIBUTES ACCESSIBLE FOR MANAGEMENT BY A JMX AGENT

     * -----------------------------------------------------

     */

 

    private String state = "initial state";

    private int nbChanges = 0;

 

    /*

     * -----------------------------------------------------

     * PROPERTY NOT ACCESSIBLE FOR MANAGEMENT BY A JMX AGENT

     * -----------------------------------------------------

     */

 

    private int nbResets = 0;