You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@avalon.apache.org by mc...@apache.org on 2002/08/03 11:29:06 UTC

cvs commit: jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/meta/verifier ComponentVerifier.java

mcconnell    2002/08/03 02:29:06

  Modified:    assembly/src/java/org/apache/excalibur/merlin
                        DefaultController.java Main.java
               assembly/src/java/org/apache/excalibur/merlin/assembly
                        ContainerManager.java TypeManager.java
               assembly/src/java/org/apache/excalibur/merlin/container
                        DefaultContainer.java
               assembly/src/java/org/apache/excalibur/merlin/kernel
                        DefaultKernel.java
               assembly/src/java/org/apache/excalibur/meta/verifier
                        ComponentVerifier.java
  Log:
  Container updated so that it is executed as a thread and establishes the type manager as the local context classloader.
  
  Revision  Changes    Path
  1.11      +4 -14     jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/DefaultController.java
  
  Index: DefaultController.java
  ===================================================================
  RCS file: /home/cvs/jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/DefaultController.java,v
  retrieving revision 1.10
  retrieving revision 1.11
  diff -u -r1.10 -r1.11
  --- DefaultController.java	2 Aug 2002 06:36:09 -0000	1.10
  +++ DefaultController.java	3 Aug 2002 09:29:05 -0000	1.11
  @@ -246,20 +246,10 @@
       */
       public void dispose()
       {
  -        if( m_status < INITIALIZED )
  +        if( m_kernel != null )
           {
  -           return;
  -        }
  -        else if( m_status < STOPPED )
  -        {
  -            try
  -            {
  -                stop();
  -            }
  -            catch( Throwable e )
  -            {
  -                // ignore
  -            }
  +            m_kernel.dispose();
  +            
           }
           m_status = DISPOSED;
       }
  
  
  
  1.12      +12 -2     jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/Main.java
  
  Index: Main.java
  ===================================================================
  RCS file: /home/cvs/jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/Main.java,v
  retrieving revision 1.11
  retrieving revision 1.12
  diff -u -r1.11 -r1.12
  --- Main.java	2 Aug 2002 06:36:09 -0000	1.11
  +++ Main.java	3 Aug 2002 09:29:05 -0000	1.12
  @@ -165,7 +165,17 @@
               {
                   public void run()
                   {
  -                    controller.stop();
  +                    try
  +                    {
  +                        controller.stop();
  +                    }
  +                    catch( Throwable e )
  +                    {
  +                    }
  +                    finally
  +                    {
  +                        controller.dispose();
  +                    }
                   }
               }
           );
  
  
  
  1.2       +14 -1     jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/assembly/ContainerManager.java
  
  Index: ContainerManager.java
  ===================================================================
  RCS file: /home/cvs/jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/assembly/ContainerManager.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- ContainerManager.java	2 Aug 2002 06:31:29 -0000	1.1
  +++ ContainerManager.java	3 Aug 2002 09:29:05 -0000	1.2
  @@ -451,6 +451,19 @@
       }
   
       //===================================================================
  +    // Disposable
  +    //===================================================================
  +
  +    public void dispose()
  +    {
  +        // need to complete this ...
  +        // if stop has ben invoked then disops has already been invoked on 
  +        // all of the component we are managing (see LifecycleHelper) - but
  +        // aside from that, we should be going though and cleaning up state 
  +        // locally 
  +    }
  +
  +    //===================================================================
       // ContainerManager
       //===================================================================
   
  
  
  
  1.4       +12 -2     jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/assembly/TypeManager.java
  
  Index: TypeManager.java
  ===================================================================
  RCS file: /home/cvs/jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/assembly/TypeManager.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- TypeManager.java	2 Aug 2002 06:36:09 -0000	1.3
  +++ TypeManager.java	3 Aug 2002 09:29:05 -0000	1.4
  @@ -30,6 +30,7 @@
   import org.apache.avalon.framework.CascadingRuntimeException;
   import org.apache.avalon.framework.configuration.Configuration;
   import org.apache.avalon.framework.activity.Initializable;
  +import org.apache.avalon.framework.activity.Disposable;
   import org.apache.avalon.framework.context.Context;
   import org.apache.avalon.framework.context.Contextualizable;
   import org.apache.avalon.framework.context.ContextException;
  @@ -61,7 +62,7 @@
    * @version $Revision$ $Date$
    */
   public abstract class TypeManager extends URLClassLoader 
  -  implements LogEnabled, Contextualizable, Initializable
  +  implements LogEnabled, Contextualizable, Initializable, Disposable
   {
       //===================================================================
       // static
  @@ -323,6 +324,15 @@
               final String error = "Unexpected exception while inspecting manifest on file: ";
               throw new TypeRuntimeException( error + url, e );
           }
  +    }
  +
  +    //===================================================================
  +    // Disposable
  +    //===================================================================
  +
  +    public void dispose()
  +    {
  +        // need to complete this 
       }
   
       //===================================================================
  
  
  
  1.22      +264 -65   jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/container/DefaultContainer.java
  
  Index: DefaultContainer.java
  ===================================================================
  RCS file: /home/cvs/jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/container/DefaultContainer.java,v
  retrieving revision 1.21
  retrieving revision 1.22
  diff -u -r1.21 -r1.22
  --- DefaultContainer.java	3 Aug 2002 03:50:06 -0000	1.21
  +++ DefaultContainer.java	3 Aug 2002 09:29:05 -0000	1.22
  @@ -88,7 +88,7 @@
    * @author <a href="mailto:mcconnell@apache.org">Stephen McConnell</a>
    * @version $Revision$ $Date$
    */
  -public class DefaultContainer extends AbstractLogEnabled implements Container, Contextualizable, Configurable, Initializable, Disposable, Startable
  +public class DefaultContainer extends AbstractLogEnabled implements Container, Contextualizable, Configurable, Initializable, Disposable, Runnable
   {
       //=======================================================================
       // static
  @@ -102,6 +102,16 @@
       private static final Resources REZ =
           ResourceManager.getPackageResources( DefaultContainer.class );
   
  +   /**
  +    * Static enumerations used in m_action and m_last where m_action is the requested 
  +    * state of the container and m_last is the current state of the container.
  +    */
  +    private static final int UNKNOWN = 0;
  +    private static final int INITIALIZE = 1;
  +    private static final int STARTUP = 2;
  +    private static final int SHUTDOWN = 3;
  +    private static final int DISPOSE = 4;
  +
       //=======================================================================
       // state
       //=======================================================================
  @@ -126,10 +136,41 @@
       */
       private boolean m_initialized = false;
   
  +   /**
  +    * Flag showing started status.
  +    */
  +    private boolean m_started = false;
  +
  +   /**
  +    * Flag showing stopped status.
  +    */
  +    private boolean m_stopped = false;
  +
  +
       private Configuration m_configuration;
   
       private XMLContainerUtil m_creator = new XMLContainerUtil();
   
  +   /**
  +    * The thread periodically checks for state change requests enter in 
  +    * the m_action state member and attemopts to bring the m_lst value to 
  +    * be equal to the m_action value and once achieved, goes off for a little 
  +    * rest.
  +    */
  +    private Integer m_action = new Integer( UNKNOWN );
  +
  +   /**
  +    * The container is managed as a thread under which the current state 
  +    * is recorded in the m_last state member.
  +    */
  +    private Integer m_last = new Integer( UNKNOWN );
  +
  +   /**
  +    * The thread group reference - used during dispose to wait for termaintaion
  +    * of subsidiary threads.
  +    */
  +    private ThreadGroup m_group;
  +
       //=======================================================================
       // Contextualizable
       //=======================================================================
  @@ -146,12 +187,18 @@
       {
           m_manager = (ContainerManager) context.get( MANAGER_KEY );
           m_descriptor = m_manager.getContainerDescriptor();
  +        m_group = new ThreadGroup( m_descriptor.getName() );
       }
   
       //=======================================================================
       // Configurable
       //=======================================================================
   
  +   /**
  +    * Provision of a configuration to the container that is used to establish
  +    * the EXPLICIT components to be included and defintion of subcontainers.
  +    * @param config the container configuration
  +    */
       public void configure( Configuration config )
       {
           m_configuration = config;
  @@ -171,6 +218,19 @@
       */
       public void initialize() throws Exception
       {
  +        synchronized( m_action )
  +        {
  +            m_action = new Integer( INITIALIZE );
  +        }
  +    }
  +
  +   /**
  +    * Implementation of the initialization method.  Initialization is handled after
  +    * a thread is established so that we can assign the manager as the thread context 
  +    * classloader.
  +    */
  +    public void handleInitialize() throws Exception
  +    {
           getLogger().debug( "initialization" );
   
           Configuration[] components = m_configuration.getChildren("component");
  @@ -204,7 +264,7 @@
           // creation of the subsidiary containers
           //
   
  -        getLogger().debug("subsidiary container creation");
  +        getLogger().debug("subsidiary container creation" );
   
           final Configuration[] configs = m_configuration.getChildren("container");
           for( int i=0; i<configs.length; i++ )
  @@ -218,10 +278,59 @@
           //
   
           m_initialized = true;
  +        m_last = new Integer( INITIALIZE );
   
       }
   
       //=======================================================================
  +    // Runnable
  +    //=======================================================================
  +
  +   /**
  +    * Invoked by the parent to initiate the thread after which the thread will 
  +    * monitor action requests arrising from initize, startup, shutdown and dispose
  +    * requests.
  +    */
  +    public void run()
  +    {
  +        if( m_manager == null )
  +          throw new IllegalStateException("Container has not been contextualized.");
  +        Thread.currentThread().setContextClassLoader( m_manager );
  +
  +        try
  +        {
  +            while( m_action.intValue() < DISPOSE )
  +            {
  +                synchronized( m_action )
  +                {
  +                    if( m_last.intValue() != m_action.intValue() )
  +                    {
  +                        switch( m_action.intValue() )
  +                        {
  +                        case INITIALIZE:
  +                          handleInitialize();
  +                          break;
  +                        case STARTUP:
  +                          handleStartup();
  +                          break;
  +                        case SHUTDOWN:
  +                          handleShutdown();
  +                          break;
  +                        }
  +                    }
  +                }
  +                sleep();
  +            }
  +            handleDispose();
  +        }
  +        catch( Throwable e )
  +        {
  +            final String error = "Unexpected error during container execution.";
  +            throw new ContainerRuntimeException( error, e );
  +        }
  +    }
  +
  +    //=======================================================================
       // Verifiable
       //=======================================================================
   
  @@ -241,53 +350,61 @@
           }
       }
   
  +
       //======================================================================
  -    // Startable
  +    // Controller
       //======================================================================
   
      /**
  -    * Method invoked by the container's container to signal the activation of 
  -    * all components.
  -    * 
  -    * @exception Exception if a start related error occurs
  +    * Request the startup of the container.
       */
  -    public void start() throws Exception
  +    public void startup() throws Exception
       {
  -        if( getLogger().isInfoEnabled() )
  +        synchronized( m_action )
           {
  -            Profile[] profiles = m_manager.getStartupGraph( false );
  -            if( profiles.length > 0 )
  -            {
  -                StringBuffer buffer = new StringBuffer();
  -                for( int i=0; i<profiles.length; i++ )
  -                {
  -                    Profile profile = profiles[i];
  -                    buffer.append( profiles[i].getName() );
  -                    if( i<(profiles.length-1) )
  -                          buffer.append(", ");
  -                }  
  -                getLogger().info("startup: " + buffer.toString() );
  -            }
  -            else
  -            {
  -                getLogger().info( "startup" );
  -            }
  +            m_action = new Integer( STARTUP );
           }
  -        m_manager.start();
       }
   
      /**
  -    * Method invoked by the container's container to signal the deactivation of 
  -    * all components.
  +    * Implementation of the container startup procedure.
  +    */
  +    private void handleStartup() throws Exception
  +    {
  +        if( !m_initialized )
  +          handleInitialize();
  +
  +        if( getLogger().isDebugEnabled() )
  +          getLogger().debug("container startup");
  +
  +        //
  +        // startup all of the components in this container 
  +        // before starting up any of the nested containers
  +        //
  +
  +        start();
  +
  +        Iterator iterator = m_containers.iterator();
  +        while( iterator.hasNext() )
  +        {
  +            ((Controller)iterator.next()).startup();
  +        }
  +
  +        getLogger().debug("container startup complete");
  +        m_started = true;
  +        m_last = new Integer( STARTUP );
  +    }
  +
  +   /**
  +    * Activate all local components.
       * 
  -    * @exception Exception if a stop related error occurs
  +    * @exception Exception if a start related error occurs
       */
  -    public void stop()
  +    private void start() throws Exception
       {
           if( getLogger().isInfoEnabled() )
           {
  -            Profile[] profiles = m_manager.getShutdownGraph();
  -        
  +            Profile[] profiles = m_manager.getStartupGraph( false );
               if( profiles.length > 0 )
               {
                   StringBuffer buffer = new StringBuffer();
  @@ -298,50 +415,34 @@
                       if( i<(profiles.length-1) )
                             buffer.append(", ");
                   }  
  -                getLogger().info("shutdown: " + buffer.toString() );
  +                getLogger().info("startup: " + buffer.toString() );
               }
               else
               {
  -                getLogger().info( "shutdown" );
  +                getLogger().info( "startup" );
               }
           }
  -        m_manager.stop();
  +        m_manager.start();
       }
   
  -    //======================================================================
  -    // Controller
  -    //======================================================================
  -
      /**
  -    * Request the startup of the managable unit.
  +    * Request the shutdown of the container.
       */
  -    public void startup() throws Exception
  +    public void shutdown()
       {
  -
  -        if( getLogger().isDebugEnabled() )
  -          getLogger().debug("container startup");
  -
  -        //
  -        // startup all of the components in this container 
  -        // before starting up any of the nested containers
  -        //
  -
  -        start();
  -
  -        Iterator iterator = m_containers.iterator();
  -        while( iterator.hasNext() )
  +        synchronized( m_action )
           {
  -            ((Controller)iterator.next()).startup();
  +            m_action = new Integer( SHUTDOWN );
           }
  -
  -        getLogger().debug("container startup complete");
       }
   
      /**
  -    * Request the shutdown of the managable unit.
  +    * Impleementation of the container shutdown process.
       */
  -    public void shutdown()
  +    public void handleShutdown()
       {
  +        if( !m_started )
  +          return;
   
           if( getLogger().isDebugEnabled() )
             getLogger().debug("container shutdown");
  @@ -360,8 +461,43 @@
           stop();
   
           getLogger().debug("container shutdown complete");
  +        m_stopped = true;
  +        m_last = new Integer( SHUTDOWN );
       }
   
  +   /**
  +    * Method invoked by the container's container to signal the deactivation of 
  +    * all components.
  +    * 
  +    * @exception Exception if a stop related error occurs
  +    */
  +    private void stop()
  +    {
  +        if( getLogger().isInfoEnabled() )
  +        {
  +            Profile[] profiles = m_manager.getShutdownGraph();
  +        
  +            if( profiles.length > 0 )
  +            {
  +                StringBuffer buffer = new StringBuffer();
  +                for( int i=0; i<profiles.length; i++ )
  +                {
  +                    Profile profile = profiles[i];
  +                    buffer.append( profiles[i].getName() );
  +                    if( i<(profiles.length-1) )
  +                          buffer.append(", ");
  +                }  
  +                getLogger().info("shutdown: " + buffer.toString() );
  +            }
  +            else
  +            {
  +                getLogger().info( "shutdown" );
  +            }
  +        }
  +        m_manager.stop();
  +    }
  +
  +
       //=======================================================================
       // Container
       //=======================================================================
  @@ -417,7 +553,40 @@
       */
       public void dispose()
       {
  +        synchronized( m_action )
  +        {
  +            m_action = new Integer( DISPOSE );
  +        }
  +    }
  +
  +   /**
  +    * Handle disposal of the container.
  +    */
  +    private void handleDispose()
  +    {
  +        if( m_started )
  +        {
  +            if( !m_stopped )
  +               handleShutdown();
  +        }
           getLogger().debug("dispose");
  +
  +        //
  +        // dispose of all of the nested containers
  +        //
  +
  +        Iterator iterator = m_containers.iterator();
  +        while( iterator.hasNext() )
  +        {
  +            ((Disposable)iterator.next()).dispose();
  +        }
  +
  +        while( m_group.activeCount() > 0 )
  +             sleep();
  +
  +        m_manager.dispose();
  +
  +        getLogger().info("done");
       }
   
       //=======================================================================
  @@ -514,10 +683,9 @@
               final String error = "Error establishing subsidiary container manager.";
               throw new ContainerException( error, e );
           }
  -
  +        
           try
           {
  -
               getLogger().info("creating subsidiary container: " + name );
               DefaultContext context = new DefaultContext();
               context.put( MANAGER_KEY, manager );
  @@ -526,11 +694,20 @@
               final String classname = 
                 config.getAttribute( "class", DefaultContainer.class.getName() );
               DefaultContainer container = createContainerInstance( manager, classname );
  -
               final Logger logger = getLogger().getChildLogger( name );
               container.enableLogging( logger );
               container.contextualize( context );
               container.configure( config );
  +
  +            Thread thread = new Thread( m_group, container, name );
  +            thread.start();
  +
  +            //
  +            // once the thread is started, the manager assigned to the context 
  +            // will be assigned as the thread's context classloader and we can 
  +            // initiate initialization with confidence
  +            //
  +
               container.initialize( );
               return container;
           }
  @@ -541,7 +718,15 @@
           }
       }
   
  -    private DefaultContainer createContainerInstance( ClassLoader loader, String classname ) throws ContainerException
  +   /**
  +    * Internel utility to create a new instance of a container based on a supplied classname.
  +    * The clasname must be a type extending the DefaultContainer class.
  +    * @param loader the classloader containing the class to be used as the container
  +    * @param classname the name of the container class
  +    * @return the new container
  +    */
  +    private DefaultContainer createContainerInstance( ClassLoader loader, String classname ) 
  +      throws ContainerException
       {
           try
           {
  @@ -551,6 +736,20 @@
           {
               final String error = "Cannot create a container from the classname: " + classname;
               throw new ContainerException( error, e );
  +        }
  +    }
  +
  +   /**
  +    * Internel utility to sleep a bit.
  +    */
  +    private void sleep()
  +    {
  +        try
  +        {
  +            Thread.currentThread().sleep( 100 );
  +        }
  +        catch( Throwable wakeup )
  +        {
           }
       }
   }
  
  
  
  1.27      +44 -6     jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/kernel/DefaultKernel.java
  
  Index: DefaultKernel.java
  ===================================================================
  RCS file: /home/cvs/jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/kernel/DefaultKernel.java,v
  retrieving revision 1.26
  retrieving revision 1.27
  diff -u -r1.26 -r1.27
  --- DefaultKernel.java	3 Aug 2002 03:50:06 -0000	1.26
  +++ DefaultKernel.java	3 Aug 2002 09:29:06 -0000	1.27
  @@ -151,8 +151,6 @@
   
       private boolean m_verified = false;
   
  -    private boolean m_initialized = false;
  -
      /**
       * The context entries available from the kernel post startup.
       */
  @@ -173,6 +171,16 @@
   
       private XMLContainerUtil m_creator = new XMLContainerUtil();
   
  +   /**
  +    * Internal reference to the thread within which the root container will execute.
  +    */
  +    private Thread m_thread;
  +
  +    private boolean m_initialized = false;
  +    private boolean m_started = false;
  +    private boolean m_stopped = false;
  +    private boolean m_disposed = false;
  +
       //=======================================================================
       // Contextualizable
       //=======================================================================
  @@ -227,6 +235,8 @@
               m_manager.contextualize( ctx );
               m_manager.initialize();
   
  +            Thread.currentThread().setContextClassLoader( m_manager );
  +
               if( getLogger() == null )
               {
                   enableLogging( m_manager.getLoggingManager().getLoggerForCategory( name ) );
  @@ -244,6 +254,7 @@
           m_container = createContainer( config );
           
           /*
  +        // ### need to resolve some problems here
           getLogger().info( "listing exportable resources" );
           Resource[] resources = getResources();
           Logger export = getLogger().getChildLogger( "export" );
  @@ -296,6 +307,10 @@
               container.enableLogging( logger );
               container.contextualize( context );
               container.configure( config );
  +            
  +		m_thread = new Thread( (Runnable) container );
  +		m_thread.start();
  +
               container.initialize( );
               return container;
           }
  @@ -332,6 +347,14 @@
           if( m_container != null )
           {
               m_container.dispose();
  +            try
  +            {
  +                m_thread.join();
  +                getLogger().info("done");
  +            }
  +            catch( InterruptedException ie )
  +            {
  +            }
           }
       }
   
  @@ -369,9 +392,8 @@
       {
           if( !m_initialized ) return;
           if( getLogger().isInfoEnabled() )
  -          getLogger().info("shutdown");
  +          getLogger().info("shutdown intiated");
           m_container.shutdown();
  -        getLogger().info("shutdown complete");
       }
   
       //=======================================================================
  @@ -380,12 +402,28 @@
   
       public void startup() throws Exception
       {
  +        if( !m_initialized )
  +          throw new IllegalStateException("not initialized");
  +        if( m_stopped )
  +          throw new IllegalStateException("already stopped");
  +        if( m_started )
  +          throw new IllegalStateException("already started");
  +
           start();
  +        m_started = true;
       }
   
       public void shutdown()
  -    {
  +    {    
  +        if( !m_initialized )
  +          throw new IllegalStateException("not initialized");
  +        if( m_stopped )
  +          throw new IllegalStateException("already stopped");
  +        if( !m_started )
  +          throw new IllegalStateException("not started");
  +
           stop();
  +        m_stopped = true;
       }
   
       //=======================================================================
  
  
  
  1.2       +11 -3     jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/meta/verifier/ComponentVerifier.java
  
  Index: ComponentVerifier.java
  ===================================================================
  RCS file: /home/cvs/jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/meta/verifier/ComponentVerifier.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- ComponentVerifier.java	5 Jul 2002 10:39:00 -0000	1.1
  +++ ComponentVerifier.java	3 Aug 2002 09:29:06 -0000	1.2
  @@ -166,9 +166,17 @@
                                  final Class clazz )
           throws VerifyException
       {
  -        verifyServiceIsaInterface( name, clazz );
           verifyServiceIsPublic( name, clazz );
  -        verifyServiceNotALifecycle( name, clazz );
  +
  +        //
  +        // the following two validation points need more work
  +        // (a) it is valid to pass a class as a service because the class may be a proxy
  +        // (b) when (a) is a class, it may be implementing lifecycle interfaces which could
  +        // could be hidden under another proxy - i.e. this more work needed
  +        //
  +
  +        //verifyServiceIsaInterface( name, clazz );
  +        //verifyServiceNotALifecycle( name, clazz );
       }
   
       /**
  
  
  

--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>