4 Replies Latest reply on Feb 8, 2010 4:48 AM by Ales Justin

    ScopeInfo's MetaData handling looks inconsistent

    Ales Justin Master

      We add/remove the MetaData with mutable key:

       public void addMetaData(MutableMetaDataRepository repository, ControllerContext context)
       {
       this.repository = repository;
       ScopeKey scope = getMutableScope();
       MetaDataRetrieval retrieval = repository.getMetaDataRetrieval(scope);
       MutableMetaDataLoader mutable;
       if (retrieval == null)
       {
       mutable = initMutableMetaDataRetrieval(repository, context, scope);
       repository.addMetaDataRetrieval(mutable);
       addedScopes.add(scope);
       }
       else
       {
       mutable = getMutableMetaDataLoader(retrieval);
       }
      
       if (mutable == null)
       {
       log.warn("MetaData context is not mutable: " + retrieval + " for " + context.toShortString());
       return;
       }
      
       updateMetaData(repository, context, mutable, true);
       }
      


      while we do a lookup with the scope key:

       public MetaData getMetaData()
       {
       if (repository == null)
       return null;
      
       return repository.getMetaData(getScope());
       }
      


      In kernel module we go over KernelMetaDataRepository::getMetaData(ControllerContext),
      which does similar + a bit more:
       public MetaData getMetaData(ControllerContext context)
       {
       MutableMetaDataRepository repository = getMetaDataRepository();
       ScopeKey scope = context.getScopeInfo().getScope();
       MetaData metaData = repository.getMetaData(scope);
       if (metaData == null)
       {
       initMetaDataRetrieval(context);
       metaData = repository.getMetaData(scope);
       if (metaData == null)
       throw new IllegalStateException("Error initialising metadata state: " + scope);
       }
       return metaData;
       }
      
       // THE MISSING PIECE
       protected MetaDataRetrieval initMetaDataRetrieval(ControllerContext context)
       {
       MutableMetaDataRepository repository = getMetaDataRepository();
       ScopeInfo scopeInfo = context.getScopeInfo();
       return scopeInfo.initMetaDataRetrieval(repository, context);
       }
      


      I guess it's the "missing piece" that makes ScopeInfo::getMetaData work for Kernel - by luck. :-)



        • 1. Re: ScopeInfo's MetaData handling looks inconsistent
          Ales Justin Master

          I added this patch, which does lazy init on ControllerContext::getScopeInfo::getMetaData.

          Or is keeping ControllerContext around bad aka too leaky?

           

          This does remove the need for MDR::getMetaData call, which would otherwise initialize MDR.

           

          Index: dependency/src/main/java/org/jboss/dependency/plugins/AbstractScopeInfo.java
          ===================================================================
          --- dependency/src/main/java/org/jboss/dependency/plugins/AbstractScopeInfo.java    (revision 76911)
          +++ dependency/src/main/java/org/jboss/dependency/plugins/AbstractScopeInfo.java    Sun Feb 07 23:37:34 CET 2010
          @@ -64,7 +64,10 @@
           
              /** The added scopes */
              private CopyOnWriteArraySet<ScopeKey> addedScopes = new CopyOnWriteArraySet<ScopeKey>();
          -   
          +
          +   /** The owning context */
          +   private ControllerContext context;
          +
              /**
               * Create a new AbstractScopeInfo.
               * 
          @@ -110,13 +113,21 @@
              {
                 if (repository == null)
                    return null;
          -      
          +
          -      return repository.getMetaData(getScope());
          +      MetaData metaData = repository.getMetaData(getScope());
          +      if (metaData == null)
          +      {
          +         initMetaDataRetrieval(repository, context);
          +         metaData = repository.getMetaData(scopeKey);
          -   }
          +      }
          +      return metaData;
          +   }
           
              public void addMetaData(MutableMetaDataRepository repository, ControllerContext context)
              {
                 this.repository = repository;
          +      this.context = context;
          +
                 ScopeKey scope = getMutableScope();
                 MetaDataRetrieval retrieval = repository.getMetaDataRetrieval(scope);
                 MutableMetaDataLoader mutable;
          @@ -130,7 +141,7 @@
                 {
                    mutable = getMutableMetaDataLoader(retrieval);
                 }
          -      
          +
                 if (mutable == null)
                 {
                    log.warn("MetaData context is not mutable: " + retrieval + " for " + context.toShortString());
          @@ -176,8 +187,9 @@
                    }
                 }
                 addedScopes.clear();
          -      this.repository = null;
          -      
          +
          +      this.context = null;
          +      this.repository = null;
              }
           
              /**
          
          
          
          • 2. Re: ScopeInfo's MetaData handling looks inconsistent
            Ales Justin Master

            Since the ScopeInfo::addMetaData api looks like it's possible to add metadata for any context,

            not just the scopeInfo's owner, I added the following check as well:

             

                  if (context != null && context.getScopeInfo() == this)
                     this.context = null;
            
            • 3. Re: ScopeInfo's MetaData handling looks inconsistent
              Kabir Khan Master

              alesj wrote:

               

              Or is keeping ControllerContext around bad aka too leaky?

               

              For contextual injection I got leaks if not clearing the ControllerContext/BeanMetaData from the dependency items on undeploy (indirectly stored by ContextualInjectionDependencyItem.injectionValueMetaData), so it could be an issue - see ContextualInjectCleanupTestCase

              • 4. Re: ScopeInfo's MetaData handling looks inconsistent
                Ales Justin Master

                For contextual injection I got leaks if not clearing the ControllerContext/BeanMetaData from the dependency items on undeploy (indirectly stored by ContextualInjectionDependencyItem.injectionValueMetaData), so it could be an issue - see ContextualInjectCleanupTestCase

                I do cleanup - in ScopeInfo::removeMetaData, so I don't think this should be an issue.

                ScopeInfo "lives" as long as ControllerContext is "alive",

                and the only way to get rid of CC, is to unwind it, which means you also hit this SI::removeMetaData.