avalon-cvs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From nic...@apache.org
Subject svn commit: rev 46037 - in avalon/trunk/runtime: . composition/api/src/java/org/apache/avalon/composition/model composition/impl composition/impl/etc/test composition/impl/src/java/org/apache/avalon/composition/model/impl composition/impl/src/test/org/apache/avalon/composition/model/impl composition/impl/src/test/org/apache/avalon/composition/model/test test/testcyclic test/testcyclic/src test/testcyclic/src/main test/testcyclic/src/main/org test/testcyclic/src/main/org/apache test/testcyclic/src/main/org/apache/avalon test/testcyclic/src/main/org/apache/avalon/test test/testcyclic/src/main/org/apache/avalon/test/testcyclic
Date Tue, 14 Sep 2004 21:04:41 GMT
Author: niclas
Date: Tue Sep 14 14:04:40 2004
New Revision: 46037

Added:
   avalon/trunk/runtime/composition/api/src/java/org/apache/avalon/composition/model/CyclicDependencyException.java   (contents, props changed)
   avalon/trunk/runtime/composition/impl/etc/test/cyclicdeps.xml   (contents, props changed)
   avalon/trunk/runtime/composition/impl/src/test/org/apache/avalon/composition/model/impl/CyclicDepsTestCase.java   (contents, props changed)
   avalon/trunk/runtime/test/testcyclic/
   avalon/trunk/runtime/test/testcyclic/build.properties   (contents, props changed)
   avalon/trunk/runtime/test/testcyclic/build.xml   (contents, props changed)
   avalon/trunk/runtime/test/testcyclic/src/
   avalon/trunk/runtime/test/testcyclic/src/main/
   avalon/trunk/runtime/test/testcyclic/src/main/org/
   avalon/trunk/runtime/test/testcyclic/src/main/org/apache/
   avalon/trunk/runtime/test/testcyclic/src/main/org/apache/avalon/
   avalon/trunk/runtime/test/testcyclic/src/main/org/apache/avalon/test/
   avalon/trunk/runtime/test/testcyclic/src/main/org/apache/avalon/test/testcyclic/
   avalon/trunk/runtime/test/testcyclic/src/main/org/apache/avalon/test/testcyclic/A.java   (contents, props changed)
   avalon/trunk/runtime/test/testcyclic/src/main/org/apache/avalon/test/testcyclic/B.java   (contents, props changed)
   avalon/trunk/runtime/test/testcyclic/src/main/org/apache/avalon/test/testcyclic/TestCyclicA.java   (contents, props changed)
   avalon/trunk/runtime/test/testcyclic/src/main/org/apache/avalon/test/testcyclic/TestCyclicB.java   (contents, props changed)
Modified:
   avalon/trunk/runtime/build.properties
   avalon/trunk/runtime/build.xml
   avalon/trunk/runtime/composition/api/src/java/org/apache/avalon/composition/model/DependencyGraph.java
   avalon/trunk/runtime/composition/impl/build.properties
   avalon/trunk/runtime/composition/impl/src/java/org/apache/avalon/composition/model/impl/DefaultContainmentModelAssemblyHelper.java
   avalon/trunk/runtime/composition/impl/src/test/org/apache/avalon/composition/model/test/AbstractTestCase.java
   avalon/trunk/runtime/index.xml
Log:
Patch sent in by Peter Neubauer that detects cyclic dependencies in the composition model.

Modified: avalon/trunk/runtime/build.properties
==============================================================================
--- avalon/trunk/runtime/build.properties	(original)
+++ avalon/trunk/runtime/build.properties	Tue Sep 14 14:04:40 2004
@@ -1,2 +1,2 @@
 project.system = ../central/system
-project.home = .
\ No newline at end of file
+project.home = .

Modified: avalon/trunk/runtime/build.xml
==============================================================================
--- avalon/trunk/runtime/build.xml	(original)
+++ avalon/trunk/runtime/build.xml	Tue Sep 14 14:04:40 2004
@@ -1,5 +1,4 @@
 <?xml version="1.0" encoding="UTF-8" ?>
-
 <project name="runtime" default="default" basedir="." xmlns:x="antlib:org.apache.avalon.tools">
 
   <property file="build.properties"/>

Added: avalon/trunk/runtime/composition/api/src/java/org/apache/avalon/composition/model/CyclicDependencyException.java
==============================================================================
--- (empty file)
+++ avalon/trunk/runtime/composition/api/src/java/org/apache/avalon/composition/model/CyclicDependencyException.java	Tue Sep 14 14:04:40 2004
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2004 Apache Software Foundation
+ * Licensed  under the  Apache License,  Version 2.0  (the "License");
+ * you may not use  this file  except in  compliance with the License.
+ * You may obtain a copy of the License at 
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed  under the  License is distributed on an "AS IS" BASIS,
+ * WITHOUT  WARRANTIES OR CONDITIONS  OF ANY KIND, either  express  or
+ * implied.
+ * 
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.avalon.composition.model;
+
+/**
+ * indicates a cyclic dependency problem in e.g. the assembly of models.
+ */
+public class CyclicDependencyException extends RuntimeException
+{
+
+    /**
+     * Default contructor
+     */
+    public CyclicDependencyException()
+    {
+        super();
+    }
+
+    /**
+     * @see RuntimeException
+     */
+    public CyclicDependencyException( String arg0 )
+    {
+        super( arg0 );
+    }
+
+    /**
+     * @see RuntimeException
+     */
+    public CyclicDependencyException( Throwable arg0 )
+    {
+        super( arg0 );
+    }
+
+    /**
+     * @see RuntimeException
+     */
+    public CyclicDependencyException( String arg0, Throwable arg1 )
+    {
+        super( arg0, arg1 );
+    }
+
+}

Modified: avalon/trunk/runtime/composition/api/src/java/org/apache/avalon/composition/model/DependencyGraph.java
==============================================================================
--- avalon/trunk/runtime/composition/api/src/java/org/apache/avalon/composition/model/DependencyGraph.java	(original)
+++ avalon/trunk/runtime/composition/api/src/java/org/apache/avalon/composition/model/DependencyGraph.java	Tue Sep 14 14:04:40 2004
@@ -29,25 +29,28 @@
 public class DependencyGraph
 {
     /**
-     * Parent Map. Components in the parent
-     * Map are potential Providers for services
-     * if no model in the current graph satisfies
-     * a dependency.
+     * Parent Map. Components in the parent Map are potential Providers for
+     * services if no model in the current graph satisfies a dependency.
      */
     private final DependencyGraph m_parent;
 
     /**
-     * The set of models declared by the container as available.
-     * Used when searching for providers/consumers.
+     * The set of models declared by the container as available. Used when
+     * searching for providers/consumers.
      */
     private final ArrayList m_models = new ArrayList();
 
     /**
-     * The child {@link DependencyGraph} objects.
-     * Possible consumers of services in this assembly.
+     * The child {@link DependencyGraph}objects. Possible consumers of services
+     * in this assembly.
      */
     private final ArrayList m_children = new ArrayList();
 
+     /**
+      * holds the models assembled in order to track circular deps etc.
+      */
+     private ArrayList m_modelsInProgress = new ArrayList();
+ 
     /**
      * Creation of a new empty dependency graph.
      */
@@ -57,11 +60,12 @@
     }
 
     /**
-     * Creation of a new dependecy graph holding a reference to a parent
-     * graph.  DeploymentModel instances in the parent graph are potential providers
-     * for services if no model in current assembly satisfies a dependency.
-     *
-     * @param parent the parent graph
+     * Creation of a new dependecy graph holding a reference to a parent graph.
+     * DeploymentModel instances in the parent graph are potential providers for
+     * services if no model in current assembly satisfies a dependency.
+     * 
+     * @param parent
+     *            the parent graph
      */
     public DependencyGraph( final DependencyGraph parent )
     {
@@ -70,8 +74,9 @@
 
     /**
      * Addition of a consumer dependency graph.
-     *
-     * @param child the child map
+     * 
+     * @param child
+     *            the child map
      */
     public void addChild( final DependencyGraph child )
     {
@@ -80,8 +85,9 @@
 
     /**
      * Removal of a consumer dependency graph.
-     *
-     * @param child the child map
+     * 
+     * @param child
+     *            the child map
      */
     public void removeChild( final DependencyGraph child )
     {
@@ -90,8 +96,9 @@
 
     /**
      * Add a model to current dependency graph.
-     *
-     * @param model the model to add to the graph
+     * 
+     * @param model
+     *            the model to add to the graph
      */
     public void add( final DeploymentModel model )
     {
@@ -103,8 +110,9 @@
 
     /**
      * Remove a model from the dependency graph.
-     *
-     * @param model the model to remove
+     * 
+     * @param model
+     *            the model to remove
      */
     public void remove( final DeploymentModel model )
     {
@@ -112,11 +120,10 @@
     }
 
     /**
-     * Get the serilized graph of {@link DeploymentModel} objects
-     * required when starting up the target. This makes sure
-     * that all providers are established before their coresponding
-     * consumers in the graph.
-     *
+     * Get the serilized graph of {@link DeploymentModel}objects required when
+     * starting up the target. This makes sure that all providers are
+     * established before their coresponding consumers in the graph.
+     * 
      * @return the ordered list of models
      */
     public DeploymentModel[] getStartupGraph()
@@ -125,20 +132,18 @@
         {
             return walkGraph( true );
         }
-        catch( Throwable e )
+        catch ( Throwable e )
         {
-            final String error = 
-              "Unexpect error while resolving startup graph.";
+            final String error = "Unexpect error while resolving startup graph.";
             throw new ModelRuntimeException( error, e );
         }
     }
 
     /**
-     * Get the serilized graph of {@link DeploymentModel} instances
-     * required when shutting down all the components. This makes
-     * sure that all consumer shutdown actions occur before their
-     * coresponding providers in graph.
-     *
+     * Get the serilized graph of {@link DeploymentModel}instances required
+     * when shutting down all the components. This makes sure that all consumer
+     * shutdown actions occur before their coresponding providers in graph.
+     * 
      * @return the ordered list of model instances
      */
     public DeploymentModel[] getShutdownGraph()
@@ -146,8 +151,8 @@
         try
         {
             return walkGraph( false );
-        } 
-        catch( Throwable e )
+        }
+        catch ( Throwable e )
         {
             final String error = "Unexpect error while resolving shutdown graph.";
             throw new ModelRuntimeException( error, e );
@@ -155,34 +160,38 @@
     }
 
     /**
-     * Get the serilized graph of {@link DeploymentModel} instances
-     * that use services of the specified model.
-     *
-     * @param model the model
+     * Get the serilized graph of {@link DeploymentModel}instances that use
+     * services of the specified model.
+     * 
+     * @param model
+     *            the model
      * @return the ordered list of consumer model instances
      */
     public DeploymentModel[] getConsumerGraph( final DeploymentModel model )
     {
-        if( m_parent != null ) return m_parent.getConsumerGraph( model );
-
+        if( m_parent != null )
+        {
+            return m_parent.getConsumerGraph( model );
+        }
         try
         {
             DeploymentModel[] graph = getComponentGraph( model, false );
             return referencedModels( model, graph );
-        } 
-        catch( Throwable e )
+        }
+        catch ( Throwable e )
         {
-            final String error =
-                    "Unexpect error while resolving consumer graph for model: " + model;
+            final String error = "Unexpect error while resolving consumer graph for model: "
+                    + model;
             throw new ModelRuntimeException( error, e );
         }
     }
 
     /**
-     * Get the serilized graph of {@link DeploymentModel} istances
-     * that provide specified model with services.
-     *
-     * @param model the model
+     * Get the serilized graph of {@link DeploymentModel}istances that provide
+     * specified model with services.
+     * 
+     * @param model
+     *            the model
      * @return the ordered list of providers
      */
     public DeploymentModel[] getProviderGraph( final DeploymentModel model )
@@ -190,11 +199,11 @@
         try
         {
             return referencedModels( model, getComponentGraph( model, true ) );
-        } 
-        catch( Throwable e )
+        }
+        catch ( Throwable e )
         {
-            final String error =
-                    "Unexpect error while resolving provider graph for: " + model;
+            final String error = "Unexpect error while resolving provider graph for: "
+                    + model;
             throw new ModelRuntimeException( error, e );
         }
     }
@@ -202,11 +211,11 @@
     /**
      * Return an model array that does not include the provided model.
      */
-    private DeploymentModel[] referencedModels( 
-      final DeploymentModel model, DeploymentModel[] models )
+    private DeploymentModel[] referencedModels( final DeploymentModel model,
+            DeploymentModel[] models )
     {
         ArrayList list = new ArrayList();
-        for( int i = 0; i < models.length; i++ )
+        for ( int i = 0; i < models.length; i++ )
         {
             if( !models[i].equals( model ) )
             {
@@ -218,31 +227,31 @@
 
     /**
      * Get the graph of a single model.
-     *
-     * @param model the target model
-     * @param providers true if traversing providers, false if consumers
-     * @return the list of models 
+     * 
+     * @param model
+     *            the target model
+     * @param providers
+     *            true if traversing providers, false if consumers
+     * @return the list of models
      */
-    private DeploymentModel[] getComponentGraph( 
-      final DeploymentModel model, final boolean providers )
+    private DeploymentModel[] getComponentGraph( final DeploymentModel model,
+            final boolean providers )
     {
         final ArrayList result = new ArrayList();
-        visitcomponent( model,
-                providers,
-                new ArrayList(),
-                result );
+        visitcomponent( model, providers, new ArrayList(), result );
 
         final DeploymentModel[] returnValue = new DeploymentModel[result.size()];
         return (DeploymentModel[]) result.toArray( returnValue );
     }
 
     /**
-     * Method to generate an ordering of nodes to traverse.
-     * It is expected that the specified components have passed
-     * verification tests and are well formed.
-     *
-     * @param direction true if forward dependencys traced, false if 
-     *   dependencies reversed
+     * Method to generate an ordering of nodes to traverse. It is expected that
+     * the specified components have passed verification tests and are well
+     * formed.
+     * 
+     * @param direction
+     *            true if forward dependencys traced, false if dependencies
+     *            reversed
      * @return the ordered model list
      */
     private DeploymentModel[] walkGraph( final boolean direction )
@@ -251,87 +260,109 @@
         final ArrayList done = new ArrayList();
 
         final int size = m_models.size();
-        for( int i = 0; i < size; i++ )
+        for ( int i = 0; i < size; i++ )
         {
-            final DeploymentModel model =
-                    (DeploymentModel) m_models.get( i );
+            final DeploymentModel model = (DeploymentModel) m_models.get( i );
 
-            visitcomponent( model,
-                    direction,
-                    done,
-                    result );
+            visitcomponent( model, direction, done, result );
         }
 
         final DeploymentModel[] returnValue = new DeploymentModel[result.size()];
+        if( m_modelsInProgress.size() != 0 )
+        {
+            throw new RuntimeException( "there where non-assembled models: "
+                    + m_modelsInProgress );
+        }
         return (DeploymentModel[]) result.toArray( returnValue );
     }
 
     /**
      * Visit a model when traversing dependencies.
-     *
-     * @param model the model
-     * @param direction true if walking tree looking for providers, else false
-     * @param done those nodes already traversed
-     * @param order the order in which nodes have already been
-     *             traversed
+     * 
+     * @param model
+     *            the model
+     * @param direction
+     *            true if walking tree looking for providers, else false
+     * @param done
+     *            those nodes already traversed
+     * @param order
+     *            the order in which nodes have already been traversed
      */
     private void visitcomponent( final DeploymentModel model,
-            final boolean direction,
-            final ArrayList done,
-            final ArrayList order )
+            final boolean direction, final ArrayList done, final ArrayList order )
     {
+        //if circular dependency
+        if( ( model instanceof ComponentModel )
+                && m_modelsInProgress.contains( model ) )
+        {
+            throw new CyclicDependencyException(
+                    "Cyclic dependency encoutered in assembly:" + model
+                            + "is already in progress stack: "
+                            + m_modelsInProgress );
+        }
         //If already visited this model return
 
-        if( done.contains( model ) ) return;
-
+        if( done.contains( model ) )
+        {
+            return;
+        }
         done.add( model );
-
+        m_modelsInProgress.add( model );
         if( direction )
         {
             visitProviders( model, done, order );
-        } 
+
+        }
         else
         {
             visitConsumers( model, done, order );
         }
 
+        m_modelsInProgress.remove( model );
         order.add( model );
     }
 
     /**
-     * Traverse graph of components that provide services to
-     * the specified model.
-     *
-     * @param model the model
+     * Traverse graph of components that provide services to the specified
+     * model.
+     * 
+     * @param model
+     *            the model to be checked
+     * @param done
+     *            the list of already checked models
+     * @param order
+     *            the order
      */
     private void visitProviders( final DeploymentModel model,
-            final ArrayList done,
-            final ArrayList order )
+            final ArrayList done, final ArrayList order )
     {
         DeploymentModel[] providers = model.getProviders();
-        for( int i = (providers.length - 1); i > -1; i-- )
+        for ( int i = ( providers.length - 1 ); i > -1; i-- )
         {
             visitcomponent( providers[i], true, done, order );
         }
     }
 
     /**
-     * Traverse all consumers of a model. I.e. all models that use
-     * service provided by the supplied model.
-     *
-     * @param model the DeploymentModel
+     * Traverse all consumers of a model. I.e. all models that use service
+     * provided by the supplied model.
+     * 
+     * @param model
+     *            the model to be checked
+     * @param done
+     *            the list of already checked models
+     * @param order
+     *            the order
      */
     private void visitConsumers( final DeploymentModel model,
-            final ArrayList done,
-            final ArrayList order )
+            final ArrayList done, final ArrayList order )
     {
         final int size = m_models.size();
-        for( int i = 0; i < size; i++ )
+        for ( int i = 0; i < size; i++ )
         {
-            final DeploymentModel other =
-                    (DeploymentModel) m_models.get( i );
+            final DeploymentModel other = (DeploymentModel) m_models.get( i );
             final DeploymentModel[] providers = other.getProviders();
-            for( int j = 0; j < providers.length; j++ )
+            for ( int j = 0; j < providers.length; j++ )
             {
                 DeploymentModel provider = providers[j];
                 if( provider.equals( model ) )
@@ -341,7 +372,7 @@
             }
         }
         final int childCount = m_children.size();
-        for( int i = 0; i < childCount; i++ )
+        for ( int i = 0; i < childCount; i++ )
         {
             final DependencyGraph map = (DependencyGraph) m_children.get( i );
             map.visitConsumers( model, done, order );

Modified: avalon/trunk/runtime/composition/impl/build.properties
==============================================================================
--- avalon/trunk/runtime/composition/impl/build.properties	(original)
+++ avalon/trunk/runtime/composition/impl/build.properties	Tue Sep 14 14:04:40 2004
@@ -1,4 +1,4 @@
 project.name = avalon-composition-impl
 project.src.main = java
 project.home = ../..
-project.system = ../../../central/system
+project.system = ../../../central/system
\ No newline at end of file

Added: avalon/trunk/runtime/composition/impl/etc/test/cyclicdeps.xml
==============================================================================
--- (empty file)
+++ avalon/trunk/runtime/composition/impl/etc/test/cyclicdeps.xml	Tue Sep 14 14:04:40 2004
@@ -0,0 +1,11 @@
+
+<container>
+<classloader>
+     <classpath>
+       <artifact>artifact:jar:avalon/test/avalon-test-testcyclic</artifact>
+     </classpath>
+   </classloader>
+   <container name="sub">
+     <component name="test-a" class="org.apache.avalon.test.testcyclic.TestCyclicA"/>
+   </container>
+</container>

Modified: avalon/trunk/runtime/composition/impl/src/java/org/apache/avalon/composition/model/impl/DefaultContainmentModelAssemblyHelper.java
==============================================================================
--- avalon/trunk/runtime/composition/impl/src/java/org/apache/avalon/composition/model/impl/DefaultContainmentModelAssemblyHelper.java	(original)
+++ avalon/trunk/runtime/composition/impl/src/java/org/apache/avalon/composition/model/impl/DefaultContainmentModelAssemblyHelper.java	Tue Sep 14 14:04:40 2004
@@ -17,6 +17,8 @@
 
 package org.apache.avalon.composition.model.impl;
 
+import java.util.HashMap;
+import java.util.Hashtable;
 import java.util.List;
 import java.util.ArrayList;
 
@@ -61,71 +63,30 @@
     // static
     //-------------------------------------------------------------------
 
-    private static final Resources REZ =
-      ResourceManager.getPackageResources( 
-        DefaultContainmentModelAssemblyHelper.class );
+    private static final Resources REZ = ResourceManager
+            .getPackageResources( DefaultContainmentModelAssemblyHelper.class );
 
     //-------------------------------------------------------------------
     // immutable state
     //-------------------------------------------------------------------
 
     private final ContainmentContext m_context;
+
     private final DefaultContainmentModel m_model;
 
     //-------------------------------------------------------------------
     // constructor
     //-------------------------------------------------------------------
 
-    public DefaultContainmentModelAssemblyHelper( 
-      ContainmentContext context, DefaultContainmentModel model )
+    public DefaultContainmentModelAssemblyHelper( ContainmentContext context,
+            DefaultContainmentModel model )
     {
         m_context = context;
         m_model = model;
     }
 
-    //-------------------------------------------------------------------
-    // implementation
-    //-------------------------------------------------------------------
-
-   /**
-    * Assemble a target model during which all deployment and runtime 
-    * dependencies are assigned a provider model.
-    *
-    * @param model the target model to be assembled
-    * @param subject the model requesting the assembly
-    */
-    public void assembleModel( DeploymentModel model, List subjects ) 
-      throws AssemblyException
-    {
-         if( null == model )
-         {
-             throw new NullPointerException( "model" );
-         }
-         if( null == subjects )
-         {
-             throw new NullPointerException( "subjects" );
-         }
-         if( subjects.contains( model ) )
-         {
-             return;
-         }
-         if( model.isAssembled() ) 
-         {
-             return;
-         }
-
-         if( model instanceof ComponentModel )
-         {
-             assembleComponent( (ComponentModel) model, subjects );
-         }
-         else
-         {
-             ContainmentModel containment = (ContainmentModel) model;
-             containment.assemble( subjects );
-         }
-    }
-
-    private void assembleComponent( ComponentModel model, List subjects ) throws AssemblyException
+    private void assembleComponent( ComponentModel model, List subjects )
+            throws AssemblyException
     {
         ModelRepository repository = m_context.getModelRepository();
 
@@ -141,25 +102,23 @@
             {
                 if( null == context.getProvider() )
                 {
-                    StagedDeliveryDescriptor phased = 
-                     (StagedDeliveryDescriptor) delivery;
+                    StagedDeliveryDescriptor phased = (StagedDeliveryDescriptor) delivery;
                     Class clazz = phased.getDeliveryInterfaceClass();
 
                     try
                     {
                         subjects.add( model );
-                        StageDescriptor stage = 
-                          new StageDescriptor( clazz.getName() );
-                        DeploymentModel provider = 
-                          findExtensionProvider( repository, stage, subjects );
+                        StageDescriptor stage = new StageDescriptor( clazz
+                                .getName() );
+                        DeploymentModel provider = findExtensionProvider(
+                                repository, stage, subjects );
                         context.setProvider( provider );
                     }
-                    catch( Throwable e )
+                    catch ( Throwable e )
                     {
-                        final String error = 
-                          "Unable to assemble component: " 
-                          + model 
-                         + " due to a component context phase handler establishment failure.";
+                        final String error = "Unable to assemble component: "
+                                + model
+                                + " due to a component context phase handler establishment failure.";
                         throw new AssemblyException( error, e );
                     }
                     finally
@@ -175,7 +134,7 @@
         //
 
         StageModel[] stages = model.getStageModels();
-        for( int i=0; i<stages.length; i++ )
+        for ( int i = 0; i < stages.length; i++ )
         {
             StageModel stage = stages[i];
             if( null == stage.getProvider() )
@@ -183,16 +142,15 @@
                 try
                 {
                     subjects.add( model );
-                    DeploymentModel provider =
-                      findExtensionProvider( repository, stage, subjects );
+                    DeploymentModel provider = findExtensionProvider(
+                            repository, stage, subjects );
                     stage.setProvider( provider );
                 }
-                catch( Throwable e )
+                catch ( Throwable e )
                 {
-                    final String error = 
-                      "Unable to assemble component: " 
-                      + model 
-                      + " due to a component extension handler establishment failure.";
+                    final String error = "Unable to assemble component: "
+                            + model
+                            + " due to a component extension handler establishment failure.";
                     throw new AssemblyException( error, e );
                 }
                 finally
@@ -207,7 +165,7 @@
         //
 
         DependencyModel[] dependencies = model.getDependencyModels();
-        for( int i=0; i < dependencies.length; i++ )
+        for ( int i = 0; i < dependencies.length; i++ )
         {
             DependencyModel dependency = dependencies[i];
             if( null == dependency.getProvider() )
@@ -215,17 +173,17 @@
                 try
                 {
                     subjects.add( model );
-                    DeploymentModel provider =
-                      findDependencyProvider( repository, dependency, subjects );
+                    DeploymentModel provider = findDependencyProvider(
+                            repository, dependency, subjects );
                     dependency.setProvider( provider );
                 }
-                catch( Throwable e )
+                catch ( Throwable e )
                 {
                     if( dependency.getDependency().isRequired() )
                     {
-                        final String error = 
-                          "Unable to assemble component: " + model 
-                          + " due to a service provider establishment failure.";
+                        final String error = "Unable to assemble component: "
+                                + model
+                                + " due to a service provider establishment failure.";
                         throw new AssemblyException( error, e );
                     }
                 }
@@ -237,47 +195,102 @@
         }
     }
 
-    private DeploymentModel findDependencyProvider( 
-      ModelRepository repository, DependencyModel dependency, List subjects )
-      throws AssemblyException
+    //-------------------------------------------------------------------
+    // implementation
+    //-------------------------------------------------------------------
+
+    /**
+     * Assemble a target model during which all deployment and runtime
+     * dependencies are assigned a provider model.
+     * 
+     * @param model
+     *            the target model to be assembled
+     * @param subject
+     *            the model requesting the assembly
+     */
+    public void assembleModel( DeploymentModel model, List subjects )
+            throws AssemblyException
     {
-        String path = dependency.getPath();
-        if( null != path )
+        if( null == model )
         {
-            DeploymentModel model = m_model.getModel( path );
-            if( null == model )
-            {
-                final String error = 
-                  "Could not locate a model at the address: [" 
-                  + path + "] in " + this + ".";
-                throw new AssemblyException( error );
-            }
-            assembleModel( model, subjects );
-            return model;
+            throw new NullPointerException( "model" );
+        }
+        if( null == subjects )
+        {
+            throw new NullPointerException( "subjects" );
+        }
+        if( subjects.contains( model ) )
+        {
+            return;
+        }
+        if( model.isAssembled() )
+        {
+            return;
+        }
+
+        if( model instanceof ComponentModel )
+        {
+            assembleComponent( (ComponentModel) model, subjects );
         }
         else
         {
-            return findDependencyProvider( 
-              repository, dependency.getDependency(), subjects );
+            ContainmentModel containment = (ContainmentModel) model;
+            containment.assemble( subjects );
+        }
+    }
+
+    /**
+     * @param dependency
+     *            the dependency to check for
+     * @param subjects
+     *            the subjects needing the dependency
+     * @throws AssemblyException
+     */
+    private void checkCyclic( DeploymentModel dependency, List subjects )
+            throws AssemblyException
+    {
+        if( subjects.contains( dependency ) )
+        {
+            throw new AssemblyException( "Cyclic Dependency: " + dependency
+                    + "is already in subject list " + subjects );
+        }
+    }
+
+    private DeploymentProfile[] findDependencyProfiles(
+            DependencyDescriptor dependency )
+    {
+        TypeRepository repository = m_context.getClassLoaderModel()
+                .getTypeRepository();
+        Type[] types = repository.getTypes( dependency );
+        try
+        {
+            return getProfiles( repository, types );
+        }
+        catch ( TypeUnknownException tue )
+        {
+            // will not happen
+            final String error = "An irrational condition has occured.";
+            throw new ModelRuntimeException( error, tue );
         }
     }
 
     DeploymentModel findDependencyProvider( DependencyDescriptor dependency )
-      throws AssemblyException
+            throws AssemblyException
     {
         ArrayList list = new ArrayList();
         ModelRepository repository = m_context.getModelRepository();
         return findDependencyProvider( repository, dependency, list );
     }
 
-    private DeploymentModel findDependencyProvider( 
-      ModelRepository repository, DependencyDescriptor dependency, List subjects )
-      throws AssemblyException
+    private DeploymentModel findDependencyProvider( ModelRepository repository,
+            DependencyDescriptor dependency, List subjects )
+            throws AssemblyException
     {
-        DeploymentModel[] candidates = 
-          repository.getCandidateProviders( dependency );
+        DeploymentModel[] candidates = repository
+                .getCandidateProviders( dependency );
         ModelSelector selector = new DefaultModelSelector();
         DeploymentModel model = selector.select( candidates, dependency );
+        //checkCyclic( model, subjects );
         if( model != null )
         {
             assembleModel( model, subjects );
@@ -285,64 +298,96 @@
         }
 
         //
-        // otherwise, check for any packaged profiles that 
+        // otherwise, check for any packaged profiles that
         // we could use to construct the model
         //
 
         DeploymentProfile[] profiles = findDependencyProfiles( dependency );
         ProfileSelector profileSelector = new DefaultProfileSelector();
-        DeploymentProfile profile = profileSelector.select( profiles, dependency );
-        if( profile != null ) 
+        DeploymentProfile profile = profileSelector.select( profiles,
+                dependency );
+        if( profile != null )
         {
             try
             {
-                DeploymentModel solution = m_model.createDeploymentModel( profile );
+                DeploymentModel solution = m_model
+                        .createDeploymentModel( profile );
                 assembleModel( solution, subjects );
                 m_model.addModel( solution );
                 return solution;
             }
-            catch( AssemblyException ae )
+            catch ( AssemblyException ae )
             {
-                final String error = 
-                  "Nested assembly failure while attempting to construct model"
-                  + " for the profile: " + profile + " for the dependency: ["
-                  + dependency + "].";
+                final String error = "Nested assembly failure while attempting to construct model"
+                        + " for the profile: "
+                        + profile
+                        + " for the dependency: [" + dependency + "].";
                 throw new AssemblyException( error, ae );
             }
-            catch( ModelException me )
+            catch ( ModelException me )
             {
-                final String error = 
-                  "Nested model failure while attempting to add model"
-                  + " for the profile: " + profile + " for the dependency: ["
-                  + dependency + "].";
+                final String error = "Nested model failure while attempting to add model"
+                        + " for the profile: "
+                        + profile
+                        + " for the dependency: [" + dependency + "].";
                 throw new AssemblyException( error, me );
             }
         }
         else
         {
-            final String error = 
-              "Unable to locate a service provider for the dependency: [ "
-              + dependency + "].";
+            final String error = "Unable to locate a service provider for the dependency: [ "
+                    + dependency + "].";
             throw new AssemblyException( error );
         }
     }
 
-    DeploymentModel findServiceProvider( ReferenceDescriptor reference )
-      throws AssemblyException
+    private DeploymentModel findDependencyProvider( ModelRepository repository,
+            DependencyModel dependency, List subjects )
+            throws AssemblyException
     {
-        ArrayList list = new ArrayList();
-        ModelRepository repository = m_context.getModelRepository();
-        return findServiceProvider( repository, reference, list );
+        String path = dependency.getPath();
+        if( null != path )
+        {
+            DeploymentModel model = m_model.getModel( path );
+            if( null == model )
+            {
+                final String error = "Could not locate a model at the address: ["
+                        + path + "] in " + this + ".";
+                throw new AssemblyException( error );
+            }
+            assembleModel( model, subjects );
+            return model;
+        }
+        else
+        {
+            return findDependencyProvider( repository, dependency
+                    .getDependency(), subjects );
+        }
+    }
+
+    private DeploymentProfile[] findExtensionProfiles( StageDescriptor stage )
+    {
+        TypeRepository repository = m_context.getClassLoaderModel()
+                .getTypeRepository();
+        Type[] types = repository.getTypes( stage );
+        try
+        {
+            return getProfiles( repository, types );
+        }
+        catch ( TypeUnknownException tue )
+        {
+            // will not happen
+            final String error = "An irrational condition has occured.";
+            throw new ModelRuntimeException( error, tue );
+        }
     }
 
-    private DeploymentModel findServiceProvider( 
-      ModelRepository repository, ReferenceDescriptor reference, List subjects )
-      throws AssemblyException
+    private DeploymentModel findExtensionProvider( ModelRepository repository,
+            StageDescriptor stage, List subjects ) throws AssemblyException
     {
-        DeploymentModel[] candidates = 
-          repository.getCandidateProviders( reference );
+        DeploymentModel[] candidates = repository.getCandidateProviders( stage );
         ModelSelector selector = new DefaultModelSelector();
-        DeploymentModel model = selector.select( candidates, reference );
+        DeploymentModel model = selector.select( candidates, stage );
         if( model != null )
         {
             assembleModel( model, subjects );
@@ -350,52 +395,50 @@
         }
 
         //
-        // otherwise, check for any packaged profiles that 
+        // otherwise, check for any packaged profiles that
         // we could use to construct the model
         //
 
-        DeploymentProfile[] profiles = findServiceProfiles( reference );
+        DeploymentProfile[] profiles = findExtensionProfiles( stage );
         ProfileSelector profileSelector = new DefaultProfileSelector();
-        DeploymentProfile profile = profileSelector.select( profiles, reference );
-        if( profile != null ) 
+        DeploymentProfile profile = profileSelector.select( profiles, stage );
+        if( profile != null )
         {
             try
             {
-                DeploymentModel solution = m_model.createDeploymentModel( profile );
+                DeploymentModel solution = m_model
+                        .createDeploymentModel( profile );
                 assembleModel( solution, subjects );
                 m_model.addModel( solution );
                 return solution;
             }
-            catch( AssemblyException ae )
+            catch ( AssemblyException ae )
             {
-                final String error = 
-                  "Nested assembly failure while attempting to construct model"
-                  + " for the profile: [" + profile + "] for the reference: ["
-                  + reference + "].";
+                final String error = "Nested assembly failure while attempting to construct model"
+                        + " for the extension profile: ["
+                        + profile
+                        + "] for the stage dependency: [" + stage + "].";
                 throw new AssemblyException( error, ae );
             }
-            catch( ModelException me )
+            catch ( ModelException me )
             {
-                final String error = 
-                  "Nested model failure while attempting to add model"
-                  + " for the profile: " + profile + " for the reference: ["
-                  + reference + "].";
+                final String error = "Nested model failure while attempting to add model"
+                        + " for the extension profile: "
+                        + profile
+                        + " for the stage dependency: [" + stage + "].";
                 throw new AssemblyException( error, me );
             }
         }
         else
         {
-            final String error = 
-              "Unable to locate a service provider for the reference: [ "
-              + reference + "].";
+            final String error = "Unable to locate a extension provider for the stage: [ "
+                    + stage + "].";
             throw new ProviderNotFoundException( error );
         }
     }
 
-
-    private DeploymentModel findExtensionProvider( 
-      ModelRepository repository, StageModel stage, List subjects )
-      throws AssemblyException
+    private DeploymentModel findExtensionProvider( ModelRepository repository,
+            StageModel stage, List subjects ) throws AssemblyException
     {
         String path = stage.getPath();
         if( null != path )
@@ -403,9 +446,8 @@
             DeploymentModel model = m_model.getModel( path );
             if( null == model )
             {
-                final String error = 
-                  "Could not locate a model at the address: [" 
-                  + path + "] in " + this + ".";
+                final String error = "Could not locate a model at the address: ["
+                        + path + "] in " + this + ".";
                 throw new AssemblyException( error );
             }
             assembleModel( model, subjects );
@@ -413,18 +455,37 @@
         }
         else
         {
-            return findExtensionProvider( repository, stage.getStage(), subjects );
+            return findExtensionProvider( repository, stage.getStage(),
+                    subjects );
+        }
+    }
+
+    private DeploymentProfile[] findServiceProfiles(
+            ReferenceDescriptor reference )
+    {
+        TypeRepository repository = m_context.getClassLoaderModel()
+                .getTypeRepository();
+        Type[] types = repository.getTypes( reference );
+        try
+        {
+            return getProfiles( repository, types );
+        }
+        catch ( TypeUnknownException tue )
+        {
+            // will not happen
+            final String error = "An irrational condition has occured.";
+            throw new ModelRuntimeException( error, tue );
         }
     }
 
-    private DeploymentModel findExtensionProvider( 
-      ModelRepository repository, StageDescriptor stage, List subjects )
-      throws AssemblyException
+    private DeploymentModel findServiceProvider( ModelRepository repository,
+            ReferenceDescriptor reference, List subjects )
+            throws AssemblyException
     {
-        DeploymentModel[] candidates = 
-          repository.getCandidateProviders( stage );
+        DeploymentModel[] candidates = repository
+                .getCandidateProviders( reference );
         ModelSelector selector = new DefaultModelSelector();
-        DeploymentModel model = selector.select( candidates, stage );
+        DeploymentModel model = selector.select( candidates, reference );
         if( model != null )
         {
             assembleModel( model, subjects );
@@ -432,107 +493,65 @@
         }
 
         //
-        // otherwise, check for any packaged profiles that 
+        // otherwise, check for any packaged profiles that
         // we could use to construct the model
         //
 
-        DeploymentProfile[] profiles = findExtensionProfiles( stage );
+        DeploymentProfile[] profiles = findServiceProfiles( reference );
         ProfileSelector profileSelector = new DefaultProfileSelector();
-        DeploymentProfile profile = profileSelector.select( profiles, stage );
-        if( profile != null ) 
+        DeploymentProfile profile = profileSelector
+                .select( profiles, reference );
+        if( profile != null )
         {
             try
             {
-                DeploymentModel solution = m_model.createDeploymentModel( profile );
+                DeploymentModel solution = m_model
+                        .createDeploymentModel( profile );
                 assembleModel( solution, subjects );
                 m_model.addModel( solution );
                 return solution;
             }
-            catch( AssemblyException ae )
+            catch ( AssemblyException ae )
             {
-                final String error = 
-                  "Nested assembly failure while attempting to construct model"
-                  + " for the extension profile: [" + profile 
-                  + "] for the stage dependency: ["
-                  + stage + "].";
+                final String error = "Nested assembly failure while attempting to construct model"
+                        + " for the profile: ["
+                        + profile
+                        + "] for the reference: [" + reference + "].";
                 throw new AssemblyException( error, ae );
             }
-            catch( ModelException me )
+            catch ( ModelException me )
             {
-                final String error = 
-                  "Nested model failure while attempting to add model"
-                  + " for the extension profile: " + profile 
-                  + " for the stage dependency: ["
-                  + stage + "].";
+                final String error = "Nested model failure while attempting to add model"
+                        + " for the profile: "
+                        + profile
+                        + " for the reference: [" + reference + "].";
                 throw new AssemblyException( error, me );
             }
         }
         else
         {
-            final String error = 
-              "Unable to locate a extension provider for the stage: [ "
-              + stage + "].";
+            final String error = "Unable to locate a service provider for the reference: [ "
+                    + reference + "].";
             throw new ProviderNotFoundException( error );
         }
     }
 
-    private DeploymentProfile[] findExtensionProfiles( StageDescriptor stage )
-    {
-        TypeRepository repository = m_context.getClassLoaderModel().getTypeRepository();
-        Type[] types = repository.getTypes( stage );
-        try
-        {
-            return getProfiles( repository, types );
-        }
-        catch( TypeUnknownException tue )
-        {
-            // will not happen
-            final String error = "An irrational condition has occured.";
-            throw new ModelRuntimeException( error, tue );
-        }
-    }
-
-    private DeploymentProfile[] findDependencyProfiles( DependencyDescriptor dependency )
-    {
-        TypeRepository repository = m_context.getClassLoaderModel().getTypeRepository();
-        Type[] types = repository.getTypes( dependency );
-        try
-        {
-            return getProfiles( repository, types );
-        }
-        catch( TypeUnknownException tue )
-        {
-            // will not happen
-            final String error = "An irrational condition has occured.";
-            throw new ModelRuntimeException( error, tue );
-        }
-    }
-
-    private DeploymentProfile[] findServiceProfiles( ReferenceDescriptor reference )
+    DeploymentModel findServiceProvider( ReferenceDescriptor reference )
+            throws AssemblyException
     {
-        TypeRepository repository = m_context.getClassLoaderModel().getTypeRepository();
-        Type[] types = repository.getTypes( reference );
-        try
-        {
-            return getProfiles( repository, types );
-        }
-        catch( TypeUnknownException tue )
-        {
-            // will not happen
-            final String error = "An irrational condition has occured.";
-            throw new ModelRuntimeException( error, tue );
-        }
+        ArrayList list = new ArrayList();
+        ModelRepository repository = m_context.getModelRepository();
+        return findServiceProvider( repository, reference, list );
     }
 
-    private DeploymentProfile[] getProfiles( TypeRepository repository, Type[] types )
-      throws TypeUnknownException
+    private DeploymentProfile[] getProfiles( TypeRepository repository,
+            Type[] types ) throws TypeUnknownException
     {
         ArrayList list = new ArrayList();
-        for( int i=0; i<types.length; i++ )
+        for ( int i = 0; i < types.length; i++ )
         {
-            DeploymentProfile[] profiles = 
-            repository.getProfiles( types[i] );
-            for( int j=0; j<profiles.length; j++ )
+            DeploymentProfile[] profiles = repository.getProfiles( types[i] );
+            for ( int j = 0; j < profiles.length; j++ )
             {
                 list.add( profiles[j] );
             }

Added: avalon/trunk/runtime/composition/impl/src/test/org/apache/avalon/composition/model/impl/CyclicDepsTestCase.java
==============================================================================
--- (empty file)
+++ avalon/trunk/runtime/composition/impl/src/test/org/apache/avalon/composition/model/impl/CyclicDepsTestCase.java	Tue Sep 14 14:04:40 2004
@@ -0,0 +1,112 @@
+/* 
+ * Copyright 2004 Apache Software Foundation
+ * Licensed  under the  Apache License,  Version 2.0  (the "License");
+ * you may not use  this file  except in  compliance with the License.
+ * You may obtain a copy of the License at 
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed  under the  License is distributed on an "AS IS" BASIS,
+ * WITHOUT  WARRANTIES OR CONDITIONS  OF ANY KIND, either  express  or
+ * implied.
+ * 
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.avalon.composition.model.impl;
+
+import org.apache.avalon.composition.model.AssemblyException;
+import org.apache.avalon.composition.model.ContainmentModel;
+import org.apache.avalon.composition.model.CyclicDependencyException;
+import org.apache.avalon.composition.model.DeploymentModel;
+import org.apache.avalon.composition.model.ModelRuntimeException;
+import org.apache.avalon.composition.model.test.AbstractTestCase;
+import org.apache.avalon.framework.logger.ConsoleLogger;
+
+/**
+ * checks that cyclic dependencies in the service declarations are properlly
+ * found and notified.
+ */
+public class CyclicDepsTestCase extends AbstractTestCase
+{
+    //-------------------------------------------------------
+    // constructor
+    //-------------------------------------------------------
+    /**
+     * the contructor
+     */
+    public CyclicDepsTestCase()
+    {
+        super();
+    }
+
+    /**
+     * @param container
+     *            the container to be printed
+     */
+    private void printStartup( ContainmentModel container )
+    {
+        DeploymentModel[] startup = container.getStartupGraph();
+        for ( int i = 0; i < startup.length; i++ )
+        {
+            DeploymentModel current = startup[i];
+            if( current instanceof ContainmentModel )
+            {
+                ContainmentModel currentContainer = (ContainmentModel) current;
+                try
+                {
+                    currentContainer.assemble();
+                    printStartup( currentContainer );
+                }
+                catch ( AssemblyException e )
+                {
+                    e.printStackTrace();
+                }
+
+            }
+            System.out.println( current.getPath() + current.getName() );
+            DeploymentModel[] deps = current.getProviders();
+
+            for ( int j = 0; j < deps.length; j++ )
+            {
+
+                System.out.println( "\tdep<-" + deps[j].getPath()
+                        + deps[j].getName() );
+
+            }
+        }
+    }
+
+    public void setUp() throws Exception
+    {
+        m_model = super.setUp( "cyclicdeps.xml" );
+        ConsoleLogger logger = new ConsoleLogger( ConsoleLogger.LEVEL_INFO );
+    }
+
+    //-------------------------------------------------------
+    // tests
+    //-------------------------------------------------------
+
+    /**
+     * Validate the the included block was created.
+     */
+    public void testCyclicDependency() throws Throwable
+    {
+        try
+        {
+
+            ContainmentModel root = (ContainmentModel) m_model.getModel( "/" );
+
+            root.assemble();
+            printStartup( root );
+            fail( "an exception should have been thrown" );
+
+        }
+        catch ( ModelRuntimeException e )
+        {
+            //this should be thrown.
+        }
+    }
+}
\ No newline at end of file

Modified: avalon/trunk/runtime/composition/impl/src/test/org/apache/avalon/composition/model/test/AbstractTestCase.java
==============================================================================
--- avalon/trunk/runtime/composition/impl/src/test/org/apache/avalon/composition/model/test/AbstractTestCase.java	(original)
+++ avalon/trunk/runtime/composition/impl/src/test/org/apache/avalon/composition/model/test/AbstractTestCase.java	Tue Sep 14 14:04:40 2004
@@ -74,7 +74,6 @@
         BASEDIR = getWorkDir();
         SYS_CONF = new File( BASEDIR, "system/kernel.xml" ).getAbsoluteFile();
         SECURITY_BUILDER = new XMLSecurityProfileBuilder();
-        System.out.println( "security.policy=" + System.getProperty( "java.security.policy" ) );
     }
     
     private static File getWorkDir()
@@ -84,12 +83,22 @@
         {
             return new File( path );
         }
-        else
+        path = System.getProperty( "basedir" );
+        if( path != null )
         {
-            path = System.getProperty( "basedir" );
             File root = new File( path );
             return new File( root, "target/test-classes" );
         }
+        
+        //still no success resort to user.dir
+        if( !(path != null) )
+        {
+        	path = System.getProperty( "user.dir" );
+        }
+        if( null != path )
+        {
+            return new File( path );
+        }	        return null;
     }
 
     //-------------------------------------------------------
@@ -174,7 +183,7 @@
         //
 
         File source = new File( BASEDIR, path );
-
+        System.out.println("loading " + source.toURL());
         return modelFactory.createRootContainmentModel( source.toURL() );
     }
 

Modified: avalon/trunk/runtime/index.xml
==============================================================================
--- avalon/trunk/runtime/index.xml	(original)
+++ avalon/trunk/runtime/index.xml	Tue Sep 14 14:04:40 2004
@@ -389,6 +389,19 @@
     </plugins>
   </project>
 
+  <project basedir="test/testcyclic">
+    <info>
+      <group>avalon/test</group>
+      <name>avalon-test-testcyclic</name>
+    </info>
+    <dependencies>
+      <include key="avalon-framework-api"/>
+    </dependencies>
+    <plugins>
+      <include key="avalon-meta-tools"/>
+    </plugins>
+  </project>
+
   <project basedir="test/includes">
     <info>
       <group>avalon/test</group>
@@ -689,9 +702,10 @@
       <include key="avalon-util-extension-impl"/>
       <include key="avalon-util-lifecycle"/>
       <include key="avalon-logging-impl" build="false" test="true"/>
-      <include key="avalon-test-dynamics" build="false" test="false"/>
-      <include key="avalon-test-includes" build="false" test="true"/>
-      <include key="avalon-logging-test" build="false" test="false"/>
+      <include key="avalon-test-dynamics" build="false" runtime="false" test="false"/>
+      <include key="avalon-test-includes" build="false" runtime="false" test="true"/>
+      <include key="avalon-test-testcyclic" build="false" runtime="false" test="false"/>
+      <include key="avalon-logging-test" build="false" runtime="false" test="false"/>
     </dependencies>
   </project>
 

Added: avalon/trunk/runtime/test/testcyclic/build.properties
==============================================================================
--- (empty file)
+++ avalon/trunk/runtime/test/testcyclic/build.properties	Tue Sep 14 14:04:40 2004
@@ -0,0 +1,3 @@
+
+project.home = ../..
+project.system = ../../../central/system

Added: avalon/trunk/runtime/test/testcyclic/build.xml
==============================================================================
--- (empty file)
+++ avalon/trunk/runtime/test/testcyclic/build.xml	Tue Sep 14 14:04:40 2004
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<project name="avalon-test-testcyclic" default="install" basedir="." 
+    xmlns:x="antlib:org.apache.avalon.tools" >
+
+  <property file="build.properties"/>
+  <import file="${project.system}/build/standard.xml"/>
+
+</project>

Added: avalon/trunk/runtime/test/testcyclic/src/main/org/apache/avalon/test/testcyclic/A.java
==============================================================================
--- (empty file)
+++ avalon/trunk/runtime/test/testcyclic/src/main/org/apache/avalon/test/testcyclic/A.java	Tue Sep 14 14:04:40 2004
@@ -0,0 +1,22 @@
+/* 
+ * Copyright 2004 Apache Software Foundation
+ * Licensed  under the  Apache License,  Version 2.0  (the "License");
+ * you may not use  this file  except in  compliance with the License.
+ * You may obtain a copy of the License at 
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed  under the  License is distributed on an "AS IS" BASIS,
+ * WITHOUT  WARRANTIES OR CONDITIONS  OF ANY KIND, either  express  or
+ * implied.
+ * 
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.avalon.test.testcyclic;
+
+public interface A
+{
+}

Added: avalon/trunk/runtime/test/testcyclic/src/main/org/apache/avalon/test/testcyclic/B.java
==============================================================================
--- (empty file)
+++ avalon/trunk/runtime/test/testcyclic/src/main/org/apache/avalon/test/testcyclic/B.java	Tue Sep 14 14:04:40 2004
@@ -0,0 +1,22 @@
+/* 
+ * Copyright 2004 Apache Software Foundation
+ * Licensed  under the  Apache License,  Version 2.0  (the "License");
+ * you may not use  this file  except in  compliance with the License.
+ * You may obtain a copy of the License at 
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed  under the  License is distributed on an "AS IS" BASIS,
+ * WITHOUT  WARRANTIES OR CONDITIONS  OF ANY KIND, either  express  or
+ * implied.
+ * 
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.avalon.test.testcyclic;
+
+public interface B
+{
+}

Added: avalon/trunk/runtime/test/testcyclic/src/main/org/apache/avalon/test/testcyclic/TestCyclicA.java
==============================================================================
--- (empty file)
+++ avalon/trunk/runtime/test/testcyclic/src/main/org/apache/avalon/test/testcyclic/TestCyclicA.java	Tue Sep 14 14:04:40 2004
@@ -0,0 +1,43 @@
+/* 
+ * Copyright 2004 Apache Software Foundation
+ * Licensed  under the  Apache License,  Version 2.0  (the "License");
+ * you may not use  this file  except in  compliance with the License.
+ * You may obtain a copy of the License at 
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed  under the  License is distributed on an "AS IS" BASIS,
+ * WITHOUT  WARRANTIES OR CONDITIONS  OF ANY KIND, either  express  or
+ * implied.
+ * 
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.avalon.test.testcyclic;
+
+import org.apache.avalon.framework.logger.AbstractLogEnabled;
+import org.apache.avalon.framework.logger.Logger;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+
+/**
+ * @avalon.component name="testcyclic" lifestyle="singleton"
+ * @avalon.service type="org.apache.avalon.test.testcyclic.A"
+ */
+public class TestCyclicA extends AbstractLogEnabled
+  implements A
+{
+   /**
+    * @avalon.dependency key="CyclicB" type="org.apache.avalon.test.testcyclic.B"
+    */
+    public void service( ServiceManager manager ) throws ServiceException
+    {
+        getLogger().info( "service stage" );
+        Logger logger = getLogger().getChildLogger( "service" );
+        logger.info( "lookup B" );
+        manager.lookup( "CyclicB" );
+        logger.info( "ok" );
+    }
+}

Added: avalon/trunk/runtime/test/testcyclic/src/main/org/apache/avalon/test/testcyclic/TestCyclicB.java
==============================================================================
--- (empty file)
+++ avalon/trunk/runtime/test/testcyclic/src/main/org/apache/avalon/test/testcyclic/TestCyclicB.java	Tue Sep 14 14:04:40 2004
@@ -0,0 +1,43 @@
+/* 
+ * Copyright 2004 Apache Software Foundation
+ * Licensed  under the  Apache License,  Version 2.0  (the "License");
+ * you may not use  this file  except in  compliance with the License.
+ * You may obtain a copy of the License at 
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed  under the  License is distributed on an "AS IS" BASIS,
+ * WITHOUT  WARRANTIES OR CONDITIONS  OF ANY KIND, either  express  or
+ * implied.
+ * 
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.avalon.test.testcyclic;
+
+import org.apache.avalon.framework.logger.AbstractLogEnabled;
+import org.apache.avalon.framework.logger.Logger;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+
+/**
+ * @avalon.component name="cyclic-b" lifestyle="singleton"
+ * @avalon.service type="org.apache.avalon.test.testcyclic.B"
+ */
+public class TestCyclicB extends AbstractLogEnabled
+  implements B
+{
+   /**
+    * @avalon.dependency key="CyclicA" type="org.apache.avalon.test.testcyclic.A"
+    */
+    public void service( ServiceManager manager ) throws ServiceException
+    {
+        getLogger().info( "service stage" );
+        Logger logger = getLogger().getChildLogger( "service" );
+        logger.info( "lookup A" );
+        manager.lookup( "CyclicA" );
+        logger.info( "ok" );
+    }
+}

---------------------------------------------------------------------
To unsubscribe, e-mail: cvs-unsubscribe@avalon.apache.org
For additional commands, e-mail: cvs-help@avalon.apache.org


Mime
View raw message