3 Replies Latest reply on Mar 5, 2010 11:27 AM by adrian.brock

    Circular Dependencies and Semi-Resolve

      https://jira.jboss.org/jira/browse/JBKERNEL-109

       

      I've committed a prototype for circular dependencies.

      This involved three main changes:

       

      1) The ability to "semiResolve" a dependency which means that you know what you want to depend on,

      but it is not in the correct state yet. However, if the only thing that is stopping it moving to the correct

      state is a circular dependency (i.e. other things in the semi-resolved state) then it will upgraded to fully resolved.

       

      2) Change AbstractDependencyItem to use an enum for the three different types of resolved states,

      resolved, semi-resolved and unresolved and track the different types in AbstractDependencyInfo for optimized processing of the

      different types.

       

      3) A change in AbstractController to introduce an "uninstalling" set like the "installing" set, to avoid recursive

      when uninstalling contexts that have circular dependencies.

       

      Caveats:

       

      * I haven't looked at adding ON_DEMAND processing, although it should be simple to add?

       

      * The semi-resolved handling only looks at contexts in the previous state to what you require.

      If they are in any earlier state then they are unresovled until they progress to the previous state.

      This avoids having to do a complicated determination on whether there is a path to break the circular dependency,

      rather than just advancing all the related semi-resolved contexts to the next state.


      Its usage should be trivial:

       

      public MyDependencyItem extends AbstractDependencyItem

      {

          public boolean resolve(Controller)

          {

               // Determine the context we want to be semi-resolved on

               ControllerContext ctx = ...;

               if (ctx == null)

                  return false;

       

               // Pass the handling to AbstractDependencyItem

               return semiResolve(ctx);

          }

      }

        • 1. Re: Circular Dependencies and Semi-Resolve
          alesj

          Does this work out-of-the-box for multiple circular depending deployments (aka OSGi bundles, which is what we're aiming for)?

           

          How are service's invalid configs reported -- A on B in ctor, and vice-versa?

          I guess they just don't ever get resolved -- failing at check complete?

          • 2. Re: Circular Dependencies and Semi-Resolve

            alesj wrote:

             

            Does this work out-of-the-box for multiple circular depending deployments (aka OSGi bundles, which is what we're aiming for)?

             

            How are service's invalid configs reported -- A on B in ctor, and vice-versa?

            I guess they just don't ever get resolved -- failing at check complete?

            Look at the tests, e.g. testTransientComplicatedCircular(), or write a new one if you think its not handled. ;-)

            I don't think I've got full coverage on the tests since there's a lot of edge-cases with the

            backwards compability handling, but I've got all of the basics.

             

            Circular dependencies will only work if the DependencyItem explicitly invokes semiResolve()

            (or it has some other way of handling it). So it doesn't change anything for existing implementations.

             

            The checkComplete() should work fine. If the circular dependency can be resolved, its DependencyItem will

            be in the RESOLVED state, so it won't appear in the IncompleteDeploymentException (IDE).

            If its only in the SEMI_RESOLVED state, i.e. something is missing, it will appear in the IDE.


            • 3. Re: Circular Dependencies and Semi-Resolve

              adrian@jboss.org wrote:

               

              Circular dependencies will only work if the DependencyItem explicitly invokes semiResolve()

              So I've still got to change the classloading's RequirementsDependencyItem to do this. ;-)