User: starksm 
  Date: 01/04/03 19:43:22

  Modified:    src/docs howtombeans.xml jbossdocs.xml
  Log:
  Set title to JBoss 2.1+ documentation
  Add simple MBean examples to howtombeans.xml
  
  Revision  Changes    Path
  1.4       +249 -4    manual/src/docs/howtombeans.xml
  
  Index: howtombeans.xml
  ===================================================================
  RCS file: /cvsroot/jboss/manual/src/docs/howtombeans.xml,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- howtombeans.xml   2001/04/02 23:30:37     1.3
  +++ howtombeans.xml   2001/04/04 02:43:21     1.4
  @@ -1,8 +1,7 @@
   <?xml version = "1.0" encoding = "UTF-8"?>
   <section id = "howto.mbeans">
        <title>How to Integrate Custom Services via MBeans</title>
  -     <para>Author:
  -             <author> 
  +     <para>Author:<author> 
                        <firstname>Scott</firstname> 
                        <surname>Stark</surname>  
                </author> 
  @@ -40,11 +39,11 @@
                        <para>JBoss manages dependencies between MBeans via the 
org.jboss.util.ServiceControl custom MBean. . The ServiceControl MBean is also loaded 
by the JMX MLet on JBoss startup. It implements the 
javax.management.NotificationListener interface to receive 
AttributeChangeNotification, MBeanServerNotification.REGISTRATION_NOTIFICATION and 
MBeanServerNotification.UNREGISTRATION_NOTIFICATION JMX events. 
AttributeChangeNotification are simply logged to the JBoss server log. The 
REGISTRATION_NOTIFICATION and UNREGISTRATION_NOTIFICATION are used to determine which 
MBeans are candidate JBoss service MBeans. The order of MBean registration is used as 
the order of service initialization and startup. The ServiceControl MBean has four key 
methods: init, start, stop and destroy.</para>
                        <section>
                                <title>The init Method</title>
  -                             <para>The ServiceControl <function>init</function> 
method is called by the JBoss server main entry point after the jboss.jcml 
configuration has been loaded. The process of loading the jboss.jcml file will have 
caused the names of all loaded MBeans to have been registered with the ServiceControl 
MBean due to the registration events posted by the MBeanServer. The 
<function>init</function> method makes a copy of curent list of MBean names and then 
proceeds to invoke the <function>init</function> method on each MBean. If successful, 
the ServiceControl MBean then registers as an NotificationListener on the MBean's name 
to receive AttributeChangeNotification from the MBean. The order of initialization is 
the order of registration which is the same as the ordering of mbean entries in the 
jboss.jcml file.</para>
  +                             <para>The ServiceControl <function>init</function> 
method is called by the JBoss server main entry point after the jboss.jcml 
configuration has been loaded. The process of loading the jboss.jcml file will have 
caused the names of all loaded MBeans to have been registered with the ServiceControl 
MBean due to the registration events posted by the MBeanServer. The 
<function>init</function> method makes a copy of curent list of MBean names and then 
proceeds to invoke the <function>init</function> method on each MBean. If successful, 
the ServiceControl MBean then registers as an NotificationListener on the MBean's name 
to receive AttributeChangeNotification from the MBean. The order of initialization is 
the order of registration which is the same as the ordering of mbean entries in the 
jboss.jcml file. When an MBean's <function>init</function> method is called, all 
MBeans that were registered ahead of it have also had their <function>init</function> 
method invoked. This gives an MBean an opportunity to check that required MBeans or 
resources exist. The MBean typically cannot utilize other MBean services at this point 
as most JBoss MBean services do not become fully functional until they have been 
started.</para>
                        </section>
                        <section>
                                <title>The start Method</title>
  -                             <para>The ServiceControl <function>start</function> 
method is called by the JBoss server main entry point after the 
<function>init</function> method. The <function>start</function> method makes a copy 
of curent list of MBean names and then proceeds to invoke the 
<function>start</function> method on each MBean.</para>
  +                             <para>The ServiceControl <function>start</function> 
method is called by the JBoss server main entry point after all MBeans have been 
<function>init</function>d. The <function>start</function> method makes a copy of 
curent list of MBean names and then proceeds to invoke the <function>start</function> 
method on each MBean. When an MBean's <function>start</function> method is called, all 
MBeans that were registered ahead of it have also had their <function>start</function> 
method invoked. It is within the <function>start</function> method that signals an 
MBean service to become fully operational.</para>
                        </section>
                        <section>
                                <title>The stop Method</title>
  @@ -71,5 +70,251 @@
                        </listitem>
                </itemizedlist>
                <para>Which approach you choose depends on whether or not you want to 
be associated with JBoss specific code. If you don't, then you would use the first 
approach. If you don't mind, then the simplest approach is to have your MBean 
interface extend from org.jboss.util.ServiceMBean and your MBean implementation class 
extend from the abstract org.jboss.util.ServiceMBeanSupport class. This class 
implements the org.jboss.util.ServiceMBean interface except for the <function>String 
getName()</function> method. ServiceMBeanSupport provides implementations of the init, 
start, stop and destroy methods that integrate logging and JBoss service state 
management. Each method delegates any subclass specific work to initService, 
startService, stopService, and destroyService methods respectively. When subclassing 
ServiceMBeanSupport you would override one or more of the initService, startService, 
stopService, and destroyService methods in addition to getName as required.</para>
  +     </section>
  +     <section>
  +             <title>Examples</title>
  +             <para>This section uses a simple MBean that binds a HashMap into the 
JBoss JNDI namespace at a location determined by its JndiName attribute. Because the 
MBean uses JNDI it depdends on the JBoss naming service MBean and therefore must use 
the JBoss MBean service pattern to be notified of when the naming service is 
available.</para>
  +             <section>
  +                     <title>JNDIMap MBean That Implements Service Methods</title>
  +                     <para>
  +                             <xref linkend = "howto.mbeans.Service"/> gives the 
MBean interface for the JNDIMap MBean that incorporates that Service interface methods 
that it needs to startup correctly. The interface includes the Service 
<function>start</function> method to be informed when all required services have been 
started and the  <function>stop</function> method to clean up the service.</para>
  +                     <figure id = "howto.mbeans.Service">
  +                             <title>JNDIMap MBean Interface and Implementation 
Based On the Service Interface</title>
  +                             <programlisting>// The JNDIMap MBean interface
  +import javax.naming.NamingException;
  +
  +public interface JNDIMapMBean
  +{
  +    public String getJndiName();
  +    public void setJndiName(String jndiName) throws NamingException;
  +    public void start() throws Exception;
  +    public void stop() throws Exception;
  +}</programlisting>
  +                             <programlisting>// The JNDIMap MBean 
implementation<![CDATA[
  +import java.io.InputStream;
  +import java.util.HashMap;
  +import javax.naming.CompositeName;
  +import javax.naming.Context;
  +import javax.naming.InitialContext;
  +import javax.naming.Name;
  +import javax.naming.NamingException;
  +import org.jboss.naming.NonSerializableFactory;
  +
  +public class JNDIMap implements JNDIMapMBean
  +{
  +    private String jndiName;
  +    private HashMap contextMap = new HashMap();
  +    private boolean started;
  +
  +    public String getJndiName()
  +    {
  +       return jndiName;
  +    }
  +    public void setJndiName(String jndiName) throws NamingException
  +    {
  +        String oldName = this.jndiName;
  +        this.jndiName = jndiName;
  +        if( started )
  +        {
  +            unbind(oldName);
  +            try
  +            {
  +                rebind();
  +            }
  +            catch(Exception e)
  +            {
  +                NamingException ne = new NamingException("Failed to update 
jndiName");
  +                ne.setRootCause(e);
  +                throw ne;
  +            }
  +        }
  +    }
  +
  +    public void start() throws Exception
  +    {
  +        started = true;
  +        rebind();
  +    }
  +
  +    public void stop()
  +    {
  +        started = false;
  +        unbind(jndiName);
  +    }
  +
  +    private static Context createContext(Context rootContext, Name name) throws 
NamingException
  +    {
  +        Context subctx = rootContext;
  +        for(int n = 0; n < name.size(); n ++)
  +        {
  +            String atom = name.get(n);
  +            try
  +            {
  +                Object obj = subctx.lookup(atom);
  +                subctx = (Context) obj;
  +            }
  +            catch(NamingException e)
  +            {        // No binding exists, create a subcontext
  +                subctx = subctx.createSubcontext(atom);
  +            }
  +        }
  +
  +        return subctx;
  +    }
  +
  +    private void rebind() throws NamingException
  +    {
  +        InitialContext rootCtx = new InitialContext();
  +        // Get the parent context into which we are to bind
  +        Name fullName = rootCtx.getNameParser("").parse(jndiName);
  +        log.debug("fullName="+fullName);
  +        Name parentName = fullName;
  +        if( fullName.size() > 1 )
  +            parentName = fullName.getPrefix(fullName.size()-1);
  +        else
  +            parentName = new CompositeName();
  +        Context parentCtx = createContext(rootCtx, parentName);
  +        Name atomName = fullName.getSuffix(fullName.size()-1);
  +        String atom = atomName.get(0);
  +        NonSerializableFactory.rebind(parentCtx, atom, contextMap);
  +    }
  +    private void unbind(String jndiName)
  +    {
  +        try
  +        {
  +            Context rootCtx = (Context) new InitialContext();
  +            rootCtx.unbind(jndiName);
  +            NonSerializableFactory.unbind(jndiName);
  +        }
  +        catch(NamingException e)
  +        {
  +            log.exception(e);
  +        }
  +    }
  +}
  +]]></programlisting>
  +                     </figure>
  +             </section>
  +             <section>
  +                     <title>JNDIMap MBean That Extends ServiceMBean</title>
  +                     <para>
  +                             <xref linkend = "howto.mbeans.ServiceMBean"/> gives 
the MBean interface for the JNDIMap MBean that extends th ServiceMBean interface. The 
implementation class then extends the ServiceMBeanSupport class and overrides the 
<function>startService</function> method to be informed when all required services 
have been started and the  <function>stopService</function> method to clean up the 
service. It also implements the abstract <function>getName</function> to return a 
descriptive name for the MBean.</para>
  +                     <figure id = "howto.mbeans.ServiceMBean">
  +                             <title>JNDIMap MBean Interface and Implementation 
Based On the ServiceMBean Interface and ServiceMBeanSupport Class</title>
  +                             <programlisting>// The JNDIMap MBean interface
  +import javax.naming.NamingException;
  +
  +public interface JNDIMapMBean extends org.jboss.util.ServiceMBean
  +{
  +    public String getJndiName();
  +    public void setJndiName(String jndiName) throws NamingException;
  +}</programlisting>
  +                             <programlisting>// The JNDIMap MBean 
implementation<![CDATA[
  +import java.io.InputStream;
  +import java.util.HashMap;
  +import javax.naming.CompositeName;
  +import javax.naming.Context;
  +import javax.naming.InitialContext;
  +import javax.naming.Name;
  +import javax.naming.NamingException;
  +import org.jboss.naming.NonSerializableFactory;
  +
  +public class JNDIMap extends org.jboss.util.ServiceMBeanSupport implements 
JNDIMapMBean
  +{
  +    private String jndiName;
  +    private HashMap contextMap = new HashMap();
  +
  +    public String getJndiName()
  +    {
  +       return jndiName;
  +    }
  +    public void setJndiName(String jndiName) throws NamingException
  +    {
  +        String oldName = this.jndiName;
  +        this.jndiName = jndiName;
  +        if( super.getState() == STARTED )
  +        {
  +            unbind(oldName);
  +            try
  +            {
  +                rebind();
  +            }
  +            catch(Exception e)
  +            {
  +                NamingException ne = new NamingException("Failed to update 
jndiName");
  +                ne.setRootCause(e);
  +                throw ne;
  +            }
  +        }
  +    }
  +
  +    public String getName()
  +    {
  +        return "JNDIMap(" + jndiName + ")";
  +    }
  +
  +    public void startService() throws Exception
  +    {
  +        rebind();
  +    }
  +
  +    public void stopService()
  +    {
  +        unbind(jndiName);
  +    }
  +
  +    private static Context createContext(Context rootContext, Name name) throws 
NamingException
  +    {
  +        Context subctx = rootContext;
  +        for(int n = 0; n < name.size(); n ++)
  +        {
  +            String atom = name.get(n);
  +            try
  +            {
  +                Object obj = subctx.lookup(atom);
  +                subctx = (Context) obj;
  +            }
  +            catch(NamingException e)
  +            {        // No binding exists, create a subcontext
  +                subctx = subctx.createSubcontext(atom);
  +            }
  +        }
  +
  +        return subctx;
  +    }
  +
  +    private void rebind() throws NamingException
  +    {
  +        InitialContext rootCtx = new InitialContext();
  +        // Get the parent context into which we are to bind
  +        Name fullName = rootCtx.getNameParser("").parse(jndiName);
  +        log.debug("fullName="+fullName);
  +        Name parentName = fullName;
  +        if( fullName.size() > 1 )
  +            parentName = fullName.getPrefix(fullName.size()-1);
  +        else
  +            parentName = new CompositeName();
  +        Context parentCtx = createContext(rootCtx, parentName);
  +        Name atomName = fullName.getSuffix(fullName.size()-1);
  +        String atom = atomName.get(0);
  +        NonSerializableFactory.rebind(parentCtx, atom, contextMap);
  +    }
  +    private void unbind(String jndiName)
  +    {
  +        try
  +        {
  +            Context rootCtx = (Context) new InitialContext();
  +            rootCtx.unbind(jndiName);
  +            NonSerializableFactory.unbind(jndiName);
  +        }
  +        catch(NamingException e)
  +        {
  +            log.exception(e);
  +        }
  +    }
  +}
  +]]></programlisting>
  +                     </figure>
  +             </section>
        </section>
   </section>
  
  
  
  1.14      +2 -2      manual/src/docs/jbossdocs.xml
  
  Index: jbossdocs.xml
  ===================================================================
  RCS file: /cvsroot/jboss/manual/src/docs/jbossdocs.xml,v
  retrieving revision 1.13
  retrieving revision 1.14
  diff -u -r1.13 -r1.14
  --- jbossdocs.xml     2001/04/03 16:47:32     1.13
  +++ jbossdocs.xml     2001/04/04 02:43:21     1.14
  @@ -25,14 +25,14 @@
        <!ENTITY howtojpda.xml SYSTEM "howtojpda.xml">
        <!ENTITY howtomssql.xml SYSTEM "howtomssql.xml">
        <!ENTITY howtojetty.xml SYSTEM "howtojetty.xml">
  -        <!ENTITY howtoverifier.xml SYSTEM "howtoverifier.xml">
  +      <!ENTITY howtoverifier.xml SYSTEM "howtoverifier.xml">
        <!ENTITY howtombeans.xml SYSTEM "howtombeans.xml">
        <!ENTITY jbosssx.xml SYSTEM "jbosssx.xml">
        <!ENTITY howtovisualagedebug.xml SYSTEM "howtovisualagedebug.xml">
   ]>
   <book>
        <bookinfo>
  -             <title>JBoss 2.0 documentation</title>
  +             <title>JBoss 2.1+ documentation</title>
                <copyright>
                        <year>2000</year>
                        <year>2001</year>
  
  
  

_______________________________________________
Jboss-development mailing list
[EMAIL PROTECTED]
http://lists.sourceforge.net/lists/listinfo/jboss-development

Reply via email to