1 2 3 Previous Next 37 Replies Latest reply on Aug 18, 2008 9:31 AM by alesj Go to original post
      • 15. Re: Integrating aop-mc-int bean metadata with AS5

         

        "kabir.khan@jboss.com" wrote:
        Because the beans that push the things into the aspectmanager are not deployed until the BeanMetaDataDeployer picks them up in the REAL stage.

        Are you suggesting that as part of my POST_CLASSLOADER deployer rip out the aop beanmetadatafactories from the deployment, and deploy them myself there? That could work, they are easily identifiable, but I didn't want to mess around with the deployment too much.


        You at least need to push the point-cut definitions into the AspectManager
        during POST_CLASSLOADER so you know which classes need weaving and where.

        The aspects themselves won't become usable until the dependencies are
        satisifed (i.e. dependencies get injected onto them during the REAL stage)
        but then nobody should be trying to use the objects until this is done
        (they should just be analysing the classes).

        • 16. Re: Integrating aop-mc-int bean metadata with AS5
          kabirkhan

          Copied from
          http://www.jboss.com/index.html?module=bb&op=viewtopic&p=4169019#4169019

          "kabir.khan@jboss.com" wrote:
          "adrian@jboss.org" wrote:
          "kabir.khan@jboss.com" wrote:
          .
          Another problem is that for scoped deployments I am changing the beans name to something unique and adding an alias annotation containing the bean name. This breaks with the new code in BeanMetaDataDeployer. I will post more on this once I have some more information about what exactly is going on...


          Why?

          You'll break all sorts of assumptions related to deployment components
          the metadata scopes, and reporting incomplete deployments if you do that wrong.

          It seems to me that you need to take a step backwards to the original problem
          and explain what you are really trying to solve, rather than try to figure out
          what has broken because you are hacking at things you shouldn't. :-)


          I spoke to Ales about this, it is (was) solving the problem mentioned here:
          http://www.jboss.com/index.html?module=bb&op=viewtopic&p=4154037#4154037
          Basically in a scoped deployment I deploy the aop beans with a new unique name, and use an annotation to create the alias, and an annotation to deploy the bean into a scoped controller.




          • 17. Re: Integrating aop-mc-int bean metadata with AS5
            kabirkhan

            The mentioned alias contains the original name of the bean

            • 18. Re: Integrating aop-mc-int bean metadata with AS5

              I made a few more comments on the original before I noticed you'd suggested
              moving the discussion here.

              SUMMARY: Although I don't know whether it is the root of your problem,
              I basically don't believe the ScopedController has been tested/integrated with either
              MDR or deployers.

              NEW on this thread: Besides the conflict on the INSTANCE scope in the MDR
              because the default is to use the bean name mentioned on the other thread,
              I also imagine the IncompleteDeploymentException processing doesn't
              know to look in the ScopedController when summarising failed dependencies.


              The mentioned alias contains the original name of the bean


              The alias has to be unique within the same namespace so I don't know what
              that achieves?

              What I need to understand is where you are changing the name.
              Although the deployers let you change most of the deployment descriptors,
              changing the identity is obviously a no-no.

              In practice, you can do it for your case as long as you do it before the
              component deployers run, because that is what creates the deployment
              components with the bean names as the id and it is from the component
              that the INSTANCE scope in the MDR is generated.

              • 19. Re: Integrating aop-mc-int bean metadata with AS5
                alesj

                 

                "adrian@jboss.org" wrote:

                I also imagine the IncompleteDeploymentException processing doesn't
                know to look in the ScopedController when summarising failed dependencies.

                This can easily be added with the work I did with @Search.
                - http://anonsvn.jboss.org/repos/jbossas/projects/microcontainer/trunk/kernel/src/tests/org/jboss/test/kernel/annotations/test/search/

                • 20. Re: Integrating aop-mc-int bean metadata with AS5
                  kabirkhan

                  I'll try to explain exactly what I am doing first. I need to do a few things in my POST_CLASSLOADER deployer org.jboss.aop.asintegration.jboss5.AbstractAopMetaDataDeployer, which handles the beans from the -aop.xml (or AOP annotations):

                  1) I set the correct name of the AspectManager bean to use for the beans installing aop artifacts, this is the one from conf/aop.xml if a "global" deployment. In the case of a scoped deployment, I register a new aop Domain, register that as a bean in the MC, and use it's name.

                  2) I also need to make sure that the pointcut expressions are deployed before any of the classes are loaded. I am currently deploying all the beanmetadata from -aop.xml myself at this stage, and stripping them out of the deployment so that they are not deployed again by BeanMetaDataDeployer. This might be overkill, maybe I should just install the pointcuts directly and allow the later deployers to install my beans as normal? I am using similar code to BeanMetaDataDeployer to deploy the beans from my deployer.

                  3) If it is a scoped deployment, I modify the names of the installed beans before deploying them, and add an alias using the original name, so that the aliases/original names of the aspects can still be used when injected into the bindings. I then add an annotation so that the PreInstallaction deploys the beans into a scoped controller for that deployment.

                  As far as I can remember from my chat with Ales, although you can have beans with the same name in sibling scopes, we also have the scenario where a scoped deployment deploys an aspect with the same name in both the "global" scope and in the "scoped" scope. The aliases/unique names are used so that AbstractController.uninstall() knows which exact bean to uninstall on undeployment.

                  Maybe the stuff you mention about the integration between the MDR and the scoped controllers is the underlying problem?

                  • 21. Re: Integrating aop-mc-int bean metadata with AS5
                    kabirkhan

                    This is probably what Adrian said earlier in that other thread, but basically when I am putting the AspectManager into the MDR that is in the main controllers MDR. Similarly, PreInstallAction uses that repository for the context's ScopeInfo. However, in DescibeAction we use the following to obtain the repository

                    KernelMetaDataRepository repository = controller.getKernel().getMetaDataRepository();
                    

                    Beans deployed to the scoped controller get a different MDR from the main one, and there is no link between the two.

                    Is adding a link possible so that there is a notion of a parent MDR?

                    • 22. Re: Integrating aop-mc-int bean metadata with AS5
                      alesj

                       

                      "kabir.khan@jboss.com" wrote:
                      Beans deployed to the scoped controller get a different MDR from the main one, and there is no link between the two.

                      No, they should get the same one.
                      See ScopedKernelInitializer.

                      • 23. Re: Integrating aop-mc-int bean metadata with AS5
                        kabirkhan

                         

                        "alesj" wrote:

                        No, they should get the same one.
                        See ScopedKernelInitializer.


                        OK, I see it now

                        • 24. Re: Integrating aop-mc-int bean metadata with AS5
                          kabirkhan

                          After a few false starts, I now see that the MDR used by DescribeAction is the same as the one that I push the correct AspectManager to use to. However, the wrong metadata is got at the DescribeAction stage. I've traced through, and will describe what is happening. Hopefully someone more familiar with the MDR can shed some light, since I am not 100% sure how this should work.

                          My code for pushing the AspectManager is

                           private String registerScopedManagerBean(int sequence, VFSDeploymentUnit unit, AspectManager scopedManager, AopMetaDataDeployerOutput output) throws DeploymentException
                           {
                           unit.getMutableMetaData().addMetaData(scopedManager, AspectManager.class);
                           }
                          


                          The mutable scope key used underneath is
                          [APPLICATION=vfszip:/Users/kabir/sourcecontrol/jboss-head/testsuite/output/lib/aop-scopeddependency-scoped.sar]
                          


                          When deploying the beans, I use the suggested
                           private void deploy(DeploymentUnit unit, BeanMetaData deployment) throws DeploymentException
                           {
                           ...
                           KernelControllerContext context = new AbstractKernelControllerContext(null, deployment, null);
                           //Make sure that the metadata from the deployment gets put into the context
                           ScopeInfo scopeInfo = context.getScopeInfo();
                           scopeInfo.setScope(unit.getScope());
                           scopeInfo.setMutableScope(unit.getMutableScope());
                           ...
                           }
                          

                          as mentioned here http://www.jboss.com/index.html?module=bb&op=viewtopic&p=4168986#4168986 the call to
                          scopedInfo.setScopeInfo(unit.getScope())
                          

                          in BeanMetaDataDeployer changes the scopeInfo.scopeKey from
                          [JVM=THIS, CLASS=org.jboss.beans.metadata.plugins.factory.GenericBeanFactory, INSTANCE=ScopedAlias_13_Factory$ScopedInterceptor, WORK=5644960]
                          

                          to
                          [JVM=THIS, APPLICATION=vfszip:/Users/kabir/sourcecontrol/jboss-head/testsuite/output/lib/aop-scopeddependency-scoped.sar, DEPLOYMENT=vfszip:/Users/kabir/sourcecontrol/jboss-head/testsuite/output/lib/aop-scopeddependency-scoped.sar]
                          

                          Should they not be merged to something like the following?
                          [JVM=THIS, APPLICATION=vfszip:/Users/kabir/sourcecontrol/jboss-head/testsuite/output/lib/aop-scopeddependency-scoped.sar, DEPLOYMENT=vfszip:/Users/kabir/sourcecontrol/jboss-head/testsuite/output/lib/aop-scopeddependency-scoped.sar, CLASS=org.jboss.beans.metadata.plugins.factory.GenericBeanFactory, INSTANCE=ScopedAlias_13_Factory$ScopedInterceptor, WORK=5644960]
                          

                          Also, the call to scopeInfo.setMutableScope changes the scopeInfo.mutableScopeKey from
                          [INSTANCE=ScopedAlias_13_Factory$ScopedInterceptor]
                          

                          to
                          [APPLICATION=vfszip:/Users/kabir/sourcecontrol/jboss-head/testsuite/output/lib/aop-scopeddependency-scoped.sar]
                          


                          As part of PreInstallAction, AbstractScopeInfo.addMetaData() adds a new MemoryMetaDataLoader under:
                          [APPLICATION=vfszip:/Users/kabir/sourcecontrol/jboss-head/testsuite/output/lib/aop-scopeddependency-scoped.sar]
                          

                          with this code
                          public void addMetaData(MutableMetaDataRepository repository, ControllerContext context)
                           {
                           this.repository = repository;
                           ScopeKey scope = getMutableScope();
                           MemoryMetaDataLoader mutable = new MemoryMetaDataLoader(scope);
                           repository.addMetaDataRetrieval(mutable);
                           addMetaData(repository, context, mutable);
                           }
                          

                          This happens for every bean, and it overwrites the existing MetaDataContext that contained the aspect manager to use, so this no longer exists in the repository. Should this check if a retrieval exists already, and add to that instead?

                          I also noticed, that in DescribeAction it obtains the metadata using the context's scope
                          [JVM=THIS, APPLICATION=vfszip:/Users/kabir/sourcecontrol/jboss-head/testsuite/output/lib/aop-scopeddependency-scoped.sar, DEPLOYMENT=vfszip:/Users/kabir/sourcecontrol/jboss-head/testsuite/output/lib/aop-scopeddependency-scoped.sar]
                          

                          This returns a MetaDataRetrieval containing retrievals with the following scope keys
                          [DEPLOYMENT=vfszip:/Users/kabir/sourcecontrol/jboss-head/testsuite/output/lib/aop-scopeddependency-scoped.sar]
                          [APPLICATION=vfszip:/Users/kabir/sourcecontrol/jboss-head/testsuite/output/lib/aop-scopeddependency-scoped.sar]
                          [JVM=THIS]
                          

                          Are CLASS and INSTANCE missing due to the change when calling scopedInfo.setScopeInfo(unit.getScope())? Inspecting this a bit further, the MetaDataRetrieval at APPLICATION level is not the same as the one stored under
                          [APPLICATION=vfszip:/Users/kabir/sourcecontrol/jboss-head/testsuite/output/lib/aop-scopeddependency-scoped.sar]
                          

                          What is/should the link be between the two?




                          • 25. Re: Integrating aop-mc-int bean metadata with AS5
                            alesj
                            • 26. Re: Integrating aop-mc-int bean metadata with AS5

                               

                              "kabir.khan@jboss.com" wrote:

                              Also, the call to scopeInfo.setMutableScope changes the scopeInfo.mutableScopeKey from
                              [INSTANCE=ScopedAlias_13_Factory$ScopedInterceptor]
                              

                              to
                              [APPLICATION=vfszip:/Users/kabir/sourcecontrol/jboss-head/testsuite/output/lib/aop-scopeddependency-scoped.sar]
                              



                              You're main problem is that you are not using the BeanMetaDataDeployer
                              (or whatever code you copied from it) properly.

                              The BeanMetaDataDeployer is designed to be run against a Component deployment
                              which will have a mutable INSTANCE scope. You're running it against the top level
                              deployment which has a mutable scope of the whole APPLICATION.

                              AbstractDeploymentContext (i.e. an application/deployment)
                              
                               public ScopeKey getMutableScope()
                               {
                               if (mutableScope == null)
                               {
                               ScopeBuilder builder = getScopeBuilder(this);
                               mutableScope = builder.getMutableDeploymentScope(this);
                               }
                               return mutableScope;
                               }
                              


                              ComponentDeploymentContext (i.e. a bean)
                               public ScopeKey getMutableScope()
                               {
                               if (mutableScope == null)
                               {
                               ScopeBuilder builder = AbstractDeploymentContext.getScopeBuilder(this);
                               mutableScope = builder.getMutableComponentScope(this);
                               }
                               return mutableScope;
                               }
                              


                              DefaultScopeBuilder
                               public ScopeKey getMutableDeploymentScope(DeploymentContext context)
                               {
                               if (context == null)
                               throw new IllegalArgumentException("Null context");
                              
                               if (context.isTopLevel())
                               return new ScopeKey(CommonLevels.APPLICATION, context.getName());
                               else
                               return new ScopeKey(CommonLevels.DEPLOYMENT, context.getName());
                               }
                              
                              ...
                              
                               public ScopeKey getMutableComponentScope(DeploymentContext context)
                               {
                               if (context == null)
                               throw new IllegalArgumentException("Null context");
                              
                               return new ScopeKey(CommonLevels.INSTANCE, context.getName());
                               }
                              


                              Similar things happen for the runtime scope except there it builds a hierarchy
                              of scopes.

                              • 27. Re: Integrating aop-mc-int bean metadata with AS5

                                 

                                "kabir.khan@jboss.com" wrote:

                                As part of PreInstallAction, AbstractScopeInfo.addMetaData() adds a new MemoryMetaDataLoader under:
                                [APPLICATION=vfszip:/Users/kabir/sourcecontrol/jboss-head/testsuite/output/lib/aop-scopeddependency-scoped.sar]
                                

                                with this code
                                public void addMetaData(MutableMetaDataRepository repository, ControllerContext context)
                                 {
                                 this.repository = repository;
                                 ScopeKey scope = getMutableScope();
                                 MemoryMetaDataLoader mutable = new MemoryMetaDataLoader(scope);
                                 repository.addMetaDataRetrieval(mutable);
                                 addMetaData(repository, context, mutable);
                                 }
                                

                                This happens for every bean, and it overwrites the existing MetaDataContext that contained the aspect manager to use, so this no longer exists in the repository. Should this check if a retrieval exists already, and add to that instead?


                                Ok, so that's a bug. It shouldn't be overridding the mutable metadata context
                                if it already exists in the repository.

                                You're seeing it because you're using the wrong scope,
                                (the application instead of the instance scope) as the mutable scope,
                                but its obviously a problem if somebody wants to setup the instance
                                scope in the deployers.

                                • 28. Re: Integrating aop-mc-int bean metadata with AS5

                                   

                                  "adrian@jboss.org" wrote:

                                  You're main problem is that you are not using the BeanMetaDataDeployer
                                  (or whatever code you copied from it) properly.

                                  The BeanMetaDataDeployer is designed to be run against a Component deployment
                                  which will have a mutable INSTANCE scope. You're running it against the top level
                                  deployment which has a mutable scope of the whole APPLICATION.


                                  A quick hack for you (though not the correct fix)
                                  would be to change your ScopeInfo initialization code to something like:

                                  // Create an instance scope
                                  ScopeKey instanceScope = new ScopeKey(new Scope(CommonLevels.INSTANCE, controllerContext.getName()));
                                  
                                  // Add the instance to the deployment scope
                                  ScopeKey deploymentScope = unit.getScope();
                                  scope = deploymentScope.clone();
                                  scope.addScope(instanceScope);
                                  
                                  // Set the hacked scopes on the controller context
                                  ScopeInfo scopeInfo = controllerContext.getScopeInfo();
                                  scopeInfo.setScope(scope);
                                  scopeInfo.setMutableScope(instanceScope);
                                  


                                  • 29. Re: Integrating aop-mc-int bean metadata with AS5
                                    alesj

                                     

                                    "adrian@jboss.org" wrote:

                                    A quick hack for you (though not the correct fix)
                                    would be to change your ScopeInfo initialization code to something like:

                                    I've already applied something similar:
                                    - http://fisheye.jboss.org/browse/JBossAS/projects/jboss-deployers/trunk/deployers-vfs/src/main/org/jboss/deployers/vfs/deployer/kernel/BeanMetaDataDeployer.java?r1=76637&r2=76811
                                    <> 113 - scopeInfo.setScope(unit.getScope());
                                     114 - scopeInfo.setMutableScope(unit.getMutableScope());
                                     117 + if (scopeInfo != null)
                                     118 + {
                                     119 + mergeScopes(scopeInfo.getScope(), unit.getScope());
                                     120 + mergeScopes(scopeInfo.getMutableScope(), unit.getMutableScope());
                                     121 + }
                                     115 122 try
                                     116 123 {
                                     117 124 controller.install(context);
                                    
                                    
                                     !
                                    
                                    
                                    
                                    …
                                    
                                     122 129 }
                                     123 130 }
                                     124 131
                                    <> 132 + /**
                                     133 + * Merge scope keys.
                                     134 + *
                                     135 + * @param contextKey the context key
                                     136 + * @param unitKey the unit key
                                     137 + */
                                     138 + protected static void mergeScopes(ScopeKey contextKey, ScopeKey unitKey)
                                     139 + {
                                     140 + if (contextKey == null)
                                     141 + return;
                                     142 + if (unitKey == null)
                                     143 + return;
                                     144 +
                                     145 + Collection<Scope> unitScopes = unitKey.getScopes();
                                     146 + if (unitScopes == null || unitScopes.isEmpty())
                                     147 + return;
                                     148 +
                                     149 + for (Scope scope : unitScopes)
                                     150 + contextKey.addScope(scope);
                                     151 + }
                                    


                                    But like I posted on the jboss-dev:
                                    "alesj wrote:

                                    The JBossAS5_trunk now boots fine with all MC snapshots.
                                    My demos also work. :-)

                                    But I haven't closed JBDEPLOY-69 yet.
                                    Any other corner case we can think of?



                                    I'll add a test for annotated beans in deployers first.
                                    And Kabir should/could also add some test exposing his work.