You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by hl...@apache.org on 2003/09/10 18:54:52 UTC

cvs commit: jakarta-commons-sandbox/hivemind/xdocs navigation.xml case1.xml

hlship      2003/09/10 09:54:52

  Modified:    hivemind/xdocs navigation.xml case1.xml
  Log:
  Protect the (not so) innocent.
  
  Revision  Changes    Path
  1.18      +2 -2      jakarta-commons-sandbox/hivemind/xdocs/navigation.xml
  
  Index: navigation.xml
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/hivemind/xdocs/navigation.xml,v
  retrieving revision 1.17
  retrieving revision 1.18
  diff -u -r1.17 -r1.18
  --- navigation.xml	9 Sep 2003 22:09:21 -0000	1.17
  +++ navigation.xml	10 Sep 2003 16:54:52 -0000	1.18
  @@ -24,7 +24,7 @@
   			<item name="Inversion of Control" href="/ioc.html"/>
   			<item name="Multi-Threading" href="/multithreading.html"/>
   			<item name="Overriding Services" href="/override.html"/>
  -			<item name="Case Study #1: Vista Startup/Shutdown"
  +			<item name="Case Study #1: Application Startup/Shutdown"
   				href="case1.html"/>
   		</menu>
   		<menu name="Resources">
  
  
  
  1.3       +91 -68    jakarta-commons-sandbox/hivemind/xdocs/case1.xml
  
  Index: case1.xml
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/hivemind/xdocs/case1.xml,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- case1.xml	9 Sep 2003 14:51:58 -0000	1.2
  +++ case1.xml	10 Sep 2003 16:54:52 -0000	1.3
  @@ -6,26 +6,33 @@
   	]>
   <document>
   	<properties>
  -		<title>Case Study #1: Vista Startup</title>
  +		<title>Case Study #1: Application Startup / Shutdown</title>
   		<author email="hlship@apache.org">Howard M. Lewis Ship</author>
   	</properties>
   	<body>
   
   <section name="Introduction">
   
  +<blockquote>
  +This case study is based on work done for my current employer, who has not (yet)
  +given approval to mention the project by name. The package names and module
  +ids have been changed, and some minor changes and simplifications have been made.
  +The actual name of the product has been disguised as <em>Oubliette</em>.
  +</blockquote>
  +
  +	
   <p>
  -<a href="http://www.webct.com/products/viewpage?name=products_vista">Vista</a> is the
  -enterprise academic software offering from WebCT. Vista is a fairly large product, consisting
  +The Oubliette product is a fairly large J2EE web application deployed into BEA WebLogic.  Oubliette consists
   of well over six thousand classes, divided into a large number of tools and services.
  -Vista has been a production project for several years, long before HiveMind was available. 
  -HiveMind's introduction into Vista (on something of a trial basis) was to cleanup the startup
  +Oubliette has been a production project for several years, long before HiveMind was available. 
  +HiveMind's introduction into Oubliette (on something of a trial basis) was to cleanup the startup
   and shutdown process for the application.
   </p>	
   
   <p>
  -Vista runs inside BEA WebLogic as an enterprise application; however, it is still logically a 
  +Oubliette runs inside BEA WebLogic as an enterprise application; however, it is still logically a 
   number of subsystems, many of which require some form of startup or shutdown logic.  For example,
  -the Vista Help service caches help data stored in the database; the Vista Mail tool sets up
  +the Oubliette Help service caches help data stored in the database; the Oubliette Mail tool sets up
   periodic database cleanup jobs.  All told, there are over 40 startup tasks, and a handful of shutdown
   tasks.
   </p>
  @@ -35,11 +42,16 @@
   A small WebLogic startup class would invoke the EJB, and the EJB would invoke static methods
   on many other classes (some of which would lookup other EJBs and invoke methods on them).  
   This approach had grown quite unwieldy, especially in light of efforts
  -to improve and modularize the Vista build process.	HiveMind was brought in to rationalize
  -this aspect of Vista, with the goal being to make the fewest possible changes
  +to improve and modularize the Oubliette build process.	HiveMind was brought in to rationalize
  +this aspect of Oubliette, with the goal being to make the fewest possible changes
   to existing code.
   </p>
   
  +<p>
  +An important aspect of startup and shutdown is the order of operations; there are dependencies between
  +different tasks that must be honored in terms of which task is executed first.	
  +</p>
  +
   </section>
   
   <section name="Overview">
  @@ -52,7 +64,7 @@
   
   <p>
   The overall approach is to provide HiveMind module deployment descriptors for the various
  -tools and services of Vista; each module  contributes tasks to a Startup or Shutdown extension point.
  +tools and services of Oubliette; each module  contributes tasks to a Startup or Shutdown extension point.
   </p>
   
   <p>
  @@ -63,17 +75,17 @@
   
   </section>
   
  -<section name="Module vista.framework.initshut">
  +<section name="Module oubliette.framework.startup">
   
   <p>
  -The <code>vista.framework.initshut</code> ("initialization and shutdown") module
  +The <code>oubliette.framework.startup</code> ("initialization and shutdown") module
   contains the services and extension points for startup and shutdown.  It also contains
   Java classes corresponding to task contributions.
   </p>	
   	
   <source><![CDATA[<?xml version="1.0"?>
  -<module id="vista.framework.initshut" version="1.0.0">
  -	<description>Module for startup and shutdown code within Vista.</description>
  +<module id="oubliette.framework.startup" version="1.0.0">
  +	<description>Module for startup and shutdown code within Oubliette.</description>
   	
   	<extension-point id="Startup">
   		<description>Defines startup tasks.</description>
  @@ -98,7 +110,7 @@
   				</attribute>
   				<rules>
   					<create-object
  -						class="com.webct.platform.framework.initshut.service.Task"
  +						class="com.oubliette.framework.startup.service.Task"
   						/>
   					<read-attribute attribute="order" property="order"
   						translator="int"/>
  @@ -121,7 +133,7 @@
   					</attribute>
   					<rules>
   						<create-object
  -							class="com.webct.platform.framework.initshut.service.StaticTask"
  +							class="com.oubliette.framework.startup.service.StaticTask"
   							/>
   						<read-attribute attribute="class" property="className"/>
   						<read-attribute attribute="method" property="methodName"
  @@ -140,13 +152,13 @@
   	
   	<extension point-id="Startup">
   		<task title="Python" order="50"
  -			class="com.webct.platform.framework.initshut.ejb.PythonStartup"/>
  +			class="com.oubliette.framework.startup.common.PythonStartup"/>
   	</extension>
   	
   	<extension point-id="Shutdown">		
   		<task title="Update Status" order="100">
   			<invoke-static
  -				class="com.webct.platform.framework.initshut.ejb.VistaStatus"
  +				class="com.oubliette.framework.startup.common.OublietteStatus"
   				method="shutdown"/>
   		</task>
   	</extension>
  @@ -154,7 +166,7 @@
   	<service id="Startup" interface="java.lang.Runnable">
   		<invoke-factory service-id="hivemind.BuilderFactory">
   			<construct
  -				class="com.webct.platform.framework.initshut.service.TaskExecutor"
  +				class="com.oubliette.framework.startup.service.TaskExecutor"
   				log-property="log"
   				messages-property="messages">
   				<set-extension-point property="tasks" point-id="Startup"/>
  @@ -167,7 +179,7 @@
   	<service id="Shutdown" interface="java.lang.Runnable">
   		<invoke-factory service-id="hivemind.BuilderFactory">
   			<construct
  -				class="com.webct.platform.framework.initshut.service.TaskExecutor"
  +				class="com.oubliette.framework.startup.service.TaskExecutor"
   				log-property="log"
   				messages-property="messages">
   				<set-extension-point property="tasks" point-id="Shutdown"/>
  @@ -182,9 +194,6 @@
   <p>
   Notes:
   <ul>
  -<li>HiveMind does not require that the module id match a package name; in this case,
  -the module id ("vista.framework.initshut") is shorter and simpler than the
  -principal package ("com.webct.platform.framework.initshut").	</li>	
   <li>
   We use the <code>ref-id</code>	 attribute of &schema; to avoid unwanted duplication.
   </li>
  @@ -192,7 +201,7 @@
   Extension points, extensions and services can be specified in any order.	
   </li>
   <li>
  -We use the simplest possible interface for the services: <code>java.lang.Runnable</code>.	
  +We use the simplest possible interface for the Startup and Shutdown services: <code>java.lang.Runnable</code>.	
   </li>
   </ul>	
   </p>
  @@ -217,7 +226,7 @@
   The task to execute is specified in one of three ways:
   <ul>
   <li>As a Java class implementing the
  -	 <code>com.webct.platform.framework.initshut.service.Executable</code> interface (using the <code>class</code> attribute)</li>
  +	 <code>com.oubliette.framework.startup.service.Executable</code> interface (using the <code>class</code> attribute)</li>
   <li>As a HiveMind service, implementing the service (using the <code>service-id</code> attribute)</li>
   <li>As a public static method of a class (using the enclosed <code>&lt;invoke-static&gt;</code> element)</li>
   </ul>
  @@ -226,7 +235,7 @@
   <p>
   The <code>Executable</code> interface is similar to the <code>java.lang.Runnable</code> interface:
   <source>
  -package com.webct.platform.framework.initshut.service;
  +package com.oubliette.framework.startup.service;
   
   /**
    * Variation of <code>java.lang.Runnable</code> that allows for
  @@ -244,7 +253,7 @@
   </p>
   
   <p>
  -Shortly, we'll see how the servlet invokes the Startup service.	
  +Shortly, we'll see how the application's master servlet invokes the Startup service.	
   </p>
   
   <p>
  @@ -260,15 +269,15 @@
   </p>	
   
   <source>
  -package com.webct.platform.framework.initshut.service;
  +package com.oubliette.framework.startup.service;
   
   import org.apache.commons.hivemind.Orderable;
   
   /**
  - * Configuration element for the <code>vista.framework.initshut.Startup</code> or
  - * <code>vista.framework.initshut.Shutdown</code>
  + * Configuration element for the <code>oubliette.framework.startup.Startup</code> or
  + * <code>oubliette.framework.startup.Shutdown</code>
    * extension points.  Each element has a title,
  - * an {@link com.webct.platform.framework.initshut.service.Executable}
  + * an {@link com.oubliette.framework.startup.service.Executable}
    * object, and an order
    * (used to sort the Startup items into an order of execution).
    */
  @@ -333,7 +342,7 @@
   </p>
   	
   <source><![CDATA[
  -package com.webct.platform.framework.initshut.service;
  +package com.oubliette.framework.startup.service;
   
   import java.util.List;
   
  @@ -342,7 +351,7 @@
   import org.apache.commons.logging.Log;
   
   /**
  - * Implementation for the <code>vista.framework.initshut.Startup</code> 
  + * Implementation for the <code>oubliette.framework.startup.Startup</code> 
    * and <code>Shutdown</code> services.
    * Reads the corresponding configuration, sorts the elements,
    * and executes each. 
  @@ -446,6 +455,20 @@
   }
   ]]>
   </source>
  +
  +<p>
  +HiveMind has a static convienience method, <code>sortOrderables()</code>, used to sort a list of Orderable
  +objects into order, which is used here. Remember that the contributions to the Startup (and Shutdown)
  +extension points are made from multiple modules and there's no way to predict in what order those contributions
  +will show up in the <code>tasks</code> property, which is why explicit sorting is necessary.
  +</p>
  +
  +<p>
  +At one time, there was a discussion about using a thread pool to allow execution of some of the tasks in parallel.
  +That's
  +a premature optimization: even with over forty startup tasks, startup still only takes about forty seconds.	
  +</p>
  +
   </subsection>
   
   <subsection name="StaticTask class">
  @@ -456,7 +479,7 @@
   </p>
   
   <source>
  -package com.webct.platform.framework.initshut.service;
  +package com.oubliette.framework.startup.service;
   
   import java.lang.reflect.InvocationTargetException;
   import java.lang.reflect.Method;
  @@ -467,7 +490,7 @@
   
   /**
    * Implementation of
  - * {@link com.webct.platform.framework.initshut.service.Executable}
  + * {@link com.oubliette.framework.startup.service.Executable}
    * that Invokes a static method on a public class.
    */
   public class StaticTask extends BaseLocatable implements Executable
  @@ -552,17 +575,17 @@
   
   <p>
   Other modules, in their HiveMind module deployment descriptors, make contributions
  -into the Startup and Shutdown extension points of the <code>vista.framework.initshut</code>
  +into the Startup and Shutdown extension points of the <code>oubliette.framework.startup</code>
   module.  For example:
   
   <source><![CDATA[
   <?xml version="1.0"?>
  -<module id="vista.coreservice.mail" version="1.0.0">
  +<module id="oubliette.coreservice.mail" version="1.0.0">
   		
  -	<extension point-id="vista.framework.initshut.Startup">
  +	<extension point-id="oubliette.framework.startup.Startup">
   
   		<task title="Mail" order="2600" 
  -			class="com.webct.platform.coreservice.mail.startup.MailStartup"/>	
  +			class="com.oubliette.coreservice.mail.startup.MailStartup"/>	
   	  
   	</extension>
   	
  @@ -575,13 +598,13 @@
   Other modules take advantage of the &lt;invoke-static&gt; element:
   
   <source><![CDATA[<?xml version="1.0"?>
  -<module id="vista.coreservice.garbagecollection" version="1.0.0">
  +<module id="oubliette.coreservice.garbagecollection" version="1.0.0">
   	
  -	<extension point-id="vista.framework.initshut.Startup">
  +	<extension point-id="oubliette.framework.startup.Startup">
   		
   		<task title="Scheduling Garbage Collection" order="3900">
   			<invoke-static
  -				class="com.webct.platform.coreservice.garbagecollection.startup.GarbageCollectionStartup"
  +				class="com.oubliette.coreservice.garbagecollection.startup.GarbageCollectionStartup"
   				/>
   		</task>
   			
  @@ -595,7 +618,7 @@
   <section name="Servlet Initialization">
   	
   <p>
  -The servlet for the web application is responsible for constructing the registry
  +The master servlet for the web application is responsible for constructing the registry
   and storing it (using <code>HiveMind.setDefault()</code>) so that
   other code may access it.
   </p>
  @@ -625,16 +648,16 @@
                HiveMind.setDefault(registry);
   
                Runnable startup =
  -                 (Runnable)registry.getService("vista.framework.initshut.Startup", Runnable.class);
  +                 (Runnable)registry.getService("oubliette.framework.startup.Startup", Runnable.class);
   
  -             LOG.info("*** Executing vista.framework.initshut.Startup service ***");
  +             LOG.info("*** Executing oubliette.framework.startup.Startup service ***");
   
                startup.run();
            }
            catch (Exception ex)
            {
                LOG.error(
  -                 "Unable to execute vista.framework.initshut.Startup service: " + ex.getMessage());
  +                 "Unable to execute oubliette.framework.startup.Startup service: " + ex.getMessage());
            }
        }
   ]]></source>
  @@ -654,20 +677,21 @@
   We take advantage of a WebLogic extension to know when the application server is being shut down.
   
   <source>
  -package com.webct.platform.framework.initshut;
  +package com.oubliette.framework.startup;
  +
   import javax.naming.InitialContext;
   import javax.rmi.PortableRemoteObject;
   
  -import com.webct.platform.framework.initshut.ejb.initshut;
  -import com.webct.platform.framework.initshut.ejb.initshutHome;
  +import com.oubliette.framework.startup.ejb.Shutdown;
  +import com.oubliette.framework.startup.ejb.ShutdownHome;
   
   /**
    * Shutdown class called by the WebLogic container.
    */
   public class Shutdown
   {
  -    private final static String INIT_EJB_JNDI_NAME =
  -        "com.webct.platform.framework.initshut.ejb.initshutHome";
  +    private final static String EJB_JNDI_NAME =
  +        "com.oubliette.framework.startup.ejb.initshutHome";
   
       /** Prevent instantiation */
       private Shutdown()
  @@ -675,19 +699,18 @@
       }
   
       /**
  -     *  Gets the initshut EJB and invokes <code>shutdown()</code>.
  +     *  Gets the Shutdown EJB and invokes <code>shutdown()</code>.
        */
   
       public static void main(String args[]) throws Exception
       {
  -        // Call the initshut EJB
           InitialContext context = new InitialContext();
  -        initshutHome home =
  -            (initshutHome)PortableRemoteObject.narrow(
  -                context.lookup(INIT_EJB_JNDI_NAME),
  -                initshutHome.class);
  +        ShutdownHome home =
  +            (ShutdownHome)PortableRemoteObject.narrow(
  +                context.lookup(EJB_JNDI_NAME),
  +                ShutdownHome.class);
                   
  -        initshut bean = (initshut)home.create();
  +        Shutdown bean = (Shutdown)home.create();
           
           bean.shutdown();
       }
  @@ -699,7 +722,7 @@
   <p>
   The implementation of the initshut EJB is similarily straight-forward:
   <source><![CDATA[
  -package com.webct.platform.framework.initshut.ejb;
  +package com.oubliette.framework.startup.ejb;
   
   import java.rmi.RemoteException;
   
  @@ -710,26 +733,26 @@
   import org.apache.commons.logging.Log;
   import org.apache.commons.logging.LogFactory;
   
  -import com.webct.platform.framework.ejb.BaseSessionBean;
  +import com.oubliette.framework.ejb.BaseSessionBean;
   
   /**
    * Handles shutdown logic.
    *
    */
   
  -public class initshutEJB extends BaseSessionBean implements Iinitshut
  +public class ShutdownEJB extends BaseSessionBean
   {
  -    private static final Log LOG = LogFactory.getLog(initshutEJB.class);
  +    private static final Log LOG = LogFactory.getLog(ShutdownEJB.class);
   
       public void ejbCreate() throws RemoteException, CreateException
       {
       }
   
       /**
  -     * Called by J2EE Container shutdown calss for Vista shutdown processing.
  +     * Called by J2EE Container shutdown calss for Oubliette shutdown processing.
        * 
        * <p>
  -     * Gets the <code>vista.framework.initshut.Shutdown</code> service and executes it.
  +     * Gets the <code>oubliette.framework.startup.Shutdown</code> service and executes it.
        * 
        */
       
  @@ -745,11 +768,11 @@
           }
   
           Runnable r =
  -            (Runnable)registry.getService("vista.framework.initshut.Shutdown", Runnable.class);
  +            (Runnable)registry.getService("oubliette.framework.startup.Shutdown", Runnable.class);
   
           r.run();
   
  -        LOG.info("**** Vista shutdown complete ****");
  +        LOG.info("**** Oubliette shutdown complete ****");
       }
   }]]>
   </source>	
  @@ -762,7 +785,7 @@
   <p>
   This case study has shown how easy it is to leverage HiveMind for a complex task. A monolithic EJB was broken down into
   tiny, agile contributions to an extension point. The startup and shutdown logic is kept close to the contributing
  -modules', in those modules' HiveMind deployment descriptor.  Contributions are in expressive, easily readable XML.
  +modules, in those modules' HiveMind deployment descriptors.  Contributions are in expressive, easily readable XML.
   </p>
   
   <p>A single class is used to implement multiple, similar services, just by