Sophie

Sophie

distrib > Mageia > 4 > x86_64 > by-pkgid > ee5115d1de8d9cf1c36a33cc4513700b > files > 1077

mx4j-manual-3.0.1-9.mga4.noarch.rpm

<html><head><META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"><title>Dynamic MBeans</title><link href="styles.css" type="text/css" rel="stylesheet"><meta content="DocBook XSL Stylesheets V1.78.1" name="generator"><link rel="home" href="index.html" title="MX4J English Documentation"><link rel="up" href="ch06.html" title="Chapter&nbsp;6.&nbsp;MX4J Tools"><link rel="prev" href="ch06.html" title="Chapter&nbsp;6.&nbsp;MX4J Tools"><link rel="next" href="ch06s03.html" title="Naming MBeans"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="navheader"><table summary="Navigation header" width="100%"><tr><th align="center" colspan="3">Dynamic MBeans</th></tr><tr><td align="left" width="20%"><a accesskey="p" href="ch06.html">Prev</a>&nbsp;</td><th align="center" width="60%">Chapter&nbsp;6.&nbsp;MX4J Tools</th><td align="right" width="20%">&nbsp;<a accesskey="n" href="ch06s03.html">Next</a></td></tr></table><hr></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="N10C45"></a>Dynamic MBeans</h2></div></div></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="N10C48"></a>AbstractDynamicMBean base class for DynamicMBean implementation</h3></div></div></div><p>
         Writing an MBean by implementing the
         <code class="classname">javax.management.DynamicMBean</code> interface can be a heavy
         and tedious task.
      </p><p>
         MX4J provides the class
         <code class="classname">mx4j.AbstractDynamicMBean</code> as a base class to implement a
         dynamic MBean.
         <br>This class handles most of the tedious work that must be done when implementing dynamic MBeans,
         so that the MBean implementor has just to override few methods to provide the needed information required
         to create the MBean.
      </p><p>
         The methods of the
         <code class="classname">AbstractDynamicMBean</code> class can be divided in 2 groups: the methods of the
         <code class="classname">DynamicMBean</code> interface and the methods added by
         <code class="classname">AbstractDynamicMBean</code> itself.
      </p><p>
         <code class="classname">AbstractDynamicMBean</code> already implements all the methods of the
         <code class="classname">DynamicMBean</code>
         interface, and normally the MBean implementor does not have to override them.
         <br>
         The methods belonging to the second group are normally overridden by the MBean implementor to provide the MBean metadata information,
         and are the following:
         </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><span style="color: red">&lt;funcdef&gt;
                  <code class="function">createMBeanAttributeInfo</code>
               &lt;/funcdef&gt;</span>, if the MBeans has manageable attributes
            </li><li class="listitem"><span style="color: red">&lt;funcdef&gt;
                  <code class="function">createMBeanOperationInfo</code>
               &lt;/funcdef&gt;</span>, if the MBeans has manageable operations
            </li><li class="listitem"><span style="color: red">&lt;funcdef&gt;
                  <code class="function">createMBeanNotificationInfo</code>
               &lt;/funcdef&gt;</span>, if the MBeans has manageable notifications
            </li><li class="listitem"><span style="color: red">&lt;funcdef&gt;
                  <code class="function">createMBeanConstructorInfo</code>
               &lt;/funcdef&gt;</span>, if the MBeans has manageable constructors
            </li><li class="listitem"><span style="color: red">&lt;funcdef&gt;
                  <code class="function">getMBeanDescription</code>
               &lt;/funcdef&gt;</span></li></ul></div><p>
      </p><p>
         A third group of methods belongs to the subclass of
         <code class="classname">AbstractDynamicMBean</code> and are the implementation
         methods, the ones that implement the functionality of the MBean itself (see below for an example).
      </p><p>
         </p><div class="example"><a name="N10C9C"></a><p class="title"><b>Example&nbsp;6.7.&nbsp;Subclassing
               <code class="classname">AbstractDynamicMBean</code>
            </b></p><div class="example-contents"><pre class="programlisting">
               
public class SimpleDynamic extends AbstractDynamicMBean
{
   /* Method of the second group that is overridden */
   protected MBeanAttributeInfo[] createMBeanAttributeInfo()
   {
      return new MBeanAttributeInfo[]
      {
         new MBeanAttributeInfo("Name", String.class.getName(), "The name", true, true, false)
      };
   }

   /* Method of the second group that is overridden */
   protected String getMBeanDescription()
   {
      return "A simple DynamicMBean";
   }

   /* Method of the third group that implements the MBean functionality */
   public String getName() { ... }

   /* Method of the third group that implements the MBean functionality */
   public void setName(String name) { ... }
}
            
            </pre></div></div><p><br class="example-break">
      </p><p>
         As you can see above, no methods from the
         <code class="classname">DynamicMBean</code> interface needs to be implemented.
         It is sufficient to override some (or all) of the methods of the second group, and provide the relative methods
         of the third group.
      </p><p>
         Normally the MBean implementor extends
         <code class="classname">AbstractDynamicMBean</code>, but if the MBean already extends another
         class it is sufficient to implement
         <code class="classname">DynamicMBean</code> and delegate to a subclass of
         <code class="classname">AbstractDynamicMBean</code>, having care of calling the
         <span style="color: red">&lt;funcdef&gt;
            <code class="function">setResource</code>
         &lt;/funcdef&gt;</span>
         method (see example below).
      </p><p>
         </p><div class="example"><a name="N10CBF"></a><p class="title"><b>Example&nbsp;6.8.&nbsp;Delegating to
               <code class="classname">AbstractDynamicMBean</code> subclass
            </b></p><div class="example-contents"><pre class="programlisting">
               
public class ComposedDynamic extends MyBaseClass implements DynamicMBean
{
   /* Create an AbstractDynamicMBean subclass */
   private AbstractDynamicMBean delegate = new AbstractDynamicMBean()
   {
      protected MBeanAttributeInfo[] createMBeanAttributeInfo()
      {
         return new MBeanAttributeInfo[]
         {
            new MBeanAttributeInfo("Status", int.class.getName(), "The status", true, true, false),
            new MBeanAttributeInfo("Enabled", boolean.class.getName(), "The enable status", true, false, true)
         };
      }

      protected MBeanOperationInfo[] createMBeanOperationInfo()
      {
         return new MBeanOperationInfo[]
         {
            new MBeanOperationInfo("enable", "Enables this MBean", new MBeanParameterInfo[0], Void.class.getName(), MBeanOperationInfo.ACTION),
            new MBeanOperationInfo("disable", "Disables this MBean", new MBeanParameterInfo[0], Void.class.getName(), MBeanOperationInfo.ACTION)
         };
      }
   };

   private int status;
   private boolean enabled;

   public ComposedDynamicMBean()
   {
      // Set the actual resource
      delegate.setResource(this);
   }

   /* Implement the methods of DynamicMBean interface to delegate to the AbstractDynamicMBean subclass */

   public Object getAttribute(String attribute) throws AttributeNotFoundException, MBeanException, ReflectionException
   {
      return delegate.getAttribute(attribute);
   }

   // Do the same with all other methods of DynamicMBean interface
   ...

   /* Methods of the third group that implements MBean functionality */

   public void setStatus(int status)
   {
      this.status = status;
   }

   public int getStatus()
   {
      return status;
   }

   public boolean isEnabled()
   {
      return this.enabled;
   }

   public void enable()
   {
      this.enabled = true;
   }

   public void disable()
   {
      this.enabled = false;
   }
}
            
            </pre></div></div><p><br class="example-break">
      </p><p>
         <code class="classname">AbstractDynamicMBean</code> can also be used for non-invasive management: if you already have a component
         but you don't want to change it to implement a management interface, you can set it as target of a subclass of
         <code class="classname">AbstractDynamicMBean</code> and provide the suitable metadata information.
      </p><p>
         </p><div class="example"><a name="N10CD3"></a><p class="title"><b>Example&nbsp;6.9.&nbsp;Subclassing
               <code class="classname">AbstractDynamicMBean</code>
            </b></p><div class="example-contents"><pre class="programlisting">
               
public class NonInvasiveDynamic extends AbstractDynamicMBean
{
   /* Methods of the second group that are overridden */
   protected MBeanOperationInfo[] createMBeanOperationInfo()
   {
      return new MBeanOperationInfo[]
      {
         new MBeanOperationInfo("start", "Starts this MBean", new MBeanParameterInfo[0], Void.class.getName(), MBeanOperationInfo.ACTION),
         new MBeanOperationInfo("stop", "Stops this MBean", new MBeanParameterInfo[0], Void.class.getName(), MBeanOperationInfo.ACTION)
      };
   }

   protected String getMBeanDescription()
   {
      return "A non invasive DynamicMBean that manages resource";
   }

   /* Constructor that takes the managed resource */
   public NonInvasiveDynamic(ExternalService service)
   {
      // Set the actual resource that this MBean represents.
      setresource(service);
   }

/* Old main, before JMX
   public static void main(String[] args) throws Exception
   {
      // Create the service
      ExternalService service = new ExternalService();

      // Start the service
      service.start();
   }
*/
   public static void main(String[] args) throws Exception
   {
      // Create the service
      ExternalService service = new ExternalService();

      MBeanServer server = MBeanServerFactory.createMBeanServer();
      NonInvasiveDynamic mbean = new NonInvasiveDynamic(service);
      ObjectName name = new ObjectName("domain:key=value");
      server.registerMBean(mbean, name);

      // Now start the service via JMX:
      // Few lines more, but now the service is manageable !
      server.invoke(name, "start", null, null);
   }
}
            
            </pre></div></div><p><br class="example-break">
      </p><p>
         The example above shows how simple can be to plug JMX into already existing architectures, and how it is possible,
         in few lines of code, to make services manageable (and remotely manageable with JSR 160) without even impacting
         already existing service's code.
      </p></div></div><div class="navfooter"><hr><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch06.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch06.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch06s03.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">Chapter&nbsp;6.&nbsp;MX4J Tools&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;Naming MBeans</td></tr></table></div></body></html>