1 2 3 Previous Next 34 Replies Latest reply on Jul 9, 2007 3:58 PM by brian.stansberry

    @JMX aspect and aop/mc integration

    kabirkhan

      In response to http://www.jboss.com/index.html?module=bb&op=viewtopic&p=3983302#3983302, I am looking at integrating the aop-mc integration code with JBoss 5. I have more or less got this working on my machine. A few things:

      1) In order for the AOPConstructorJoinpointFactory to be used, I have had to add jboss-aop-mc-int.jar to the root jboss/lib directory since the check done by the PropertyConfiguration is done when first started. Unless I move

      server/xxx/lib/javassist.jar
      server/xxx/deployers/jboss-aop-jboss5.deployer/jboss-aop-jdk50.jar
      server/xxx/deployers/jboss-aop-jboss5.deployer/trove.jar

      into jboss/lib as well I get NoClassDefFoundErrors when accessing the jboss-aop-mc-int.jar classes - probably because the classloader used for loading up the jboss/lib classes cannot see the classes loaded up from the server/xxx/lib and server/xxx/deployers directory.

      2) It slows the startup time of the default configuration from about 37s to 45s on my machine. The AspectManagerService currently has an "exclude" property to set all classes starting with "org.jboss." to not be transformed/inspected, which works on the underlying AspectManager singleton. However the AspectManagerService is installed as part of the AspectDeployer, which is one of the last deployers to be deployed, meaning that inspection is done of all beans before it has been installed since the AspectManagerService has not yet been installed. This is also controllable via system properties, so the run.sh/.bat files could be modified to use that, so that this is picked up before the AspectManagerService has been installed. I think I would prefer some way for inspection of classes to be "turned off", until the AspectManagerService has been installed. Is there a way to swap out the ConstructorJoinPointFactory returned by the AOPJoinpointFactoryBuilder at runtime, so that it returns the BasicJoinpointFactory until the AspectManagerService is installed, and the AOPJoinpointFactory after the AspectManagerService has been installed? I can think of at least one hacky way to do this :-)

      I guess the question is, do we want the mc, and deployers installed before the AspectDeployer, to have this integration with the aspect layer or not? Do we care about the performance at this stage?

        • 1. Re: @JMX aspect and aop/mc integration
          starksm64

          I believe the aop abstraction needs to be a core part of the bootstrap kernel configuration. I'm not following how the AspectDeployer fits into your question.

          • 2. Re: @JMX aspect and aop/mc integration
            kabirkhan

            The AspectDeployer is currently deployed under deployers/jboss-aop-jboss5.deployer/META-INF/ and its deployment order relative to the other deployers seems to be arbitrary.

            I think from your answer that you are saying that we want the aop integration to be deployd as part of the server bootstrap? Meaning that the aspect deployer and the @JMX stuff is available by the time we get to scanning the deploy folder. In which case moving all the required bits into jboss/lib should be fine?

            • 3. Re: @JMX aspect and aop/mc integration
              kabirkhan

               

              "kabir.khan@jboss.com" wrote:
              Meaning that the aspect deployer and the @JMX stuff is available by the time we get to scanning the deploy folder.


              Should be

              "kabir.khan@jboss.com" wrote:
              Meaning that the aspect deployer and the @JMX stuff is available by the time we get to scanning the deployers folder.



              • 4. Re: @JMX aspect and aop/mc integration
                starksm64

                 

                "kabir.khan@jboss.com" wrote:

                I think from your answer that you are saying that we want the aop integration to be deployd as part of the server bootstrap? Meaning that the aspect deployer and the @JMX stuff is available by the time we get to scanning the deploy folder. In which case moving all the required bits into jboss/lib should be fine?

                Yes, moving this to the bootstrap lib should be fine. It does bring up the issue of javassist users now being coupled to that version, so we will run into the issue of javassit being an implementation detail of the mc, or part of its public api that other deployments should interact with.


                • 5. Re: @JMX aspect and aop/mc integration
                  starksm64

                  Speaking of the @JMX, I don't think we want these aspects in the bootstrap dependencies. Should we have a separate mc aspects project?

                  • 6. Re: @JMX aspect and aop/mc integration
                    kabirkhan

                    Do we want the deployers/ beans to be annotatable with @JMX? If we do, I think we either want them to be in the bootstrap, or have some way to order the deployments within the deployers/ directory?

                    I'll aim to get what I have working today, and then we can move it around

                    • 7. Re: @JMX aspect and aop/mc integration
                      starksm64

                      In terms of ordering, beans/deployers that depend on aspects coming in with the AspectDeployer should just be depending on it.

                      • 8. Re: @JMX aspect and aop/mc integration
                        kabirkhan

                        I have committed an initial version of this. I have left the jboss-aop-jboss5.deployer as it was and split the jboss-aop-mc-int.jar into

                        jboss/
                         lib/
                         jboss-aop-mc-int-boot.jar
                         server/
                         xxx/
                         deployers/
                         jboss-aop-jboss5.deployer
                         jboss-aop-mc-int-deployer.jar
                         jboss-aop-jdk50.jar
                         ...
                         aop-mc-int-aspect-beans.xml (contains the definitions needed for the @JMX aspect)
                        


                        The boot.jar contains the necessary hooks for being picked up by the mc (AOPJoinpointFactory, AOPMetadataContextFactory and AOPDependencyBuilder). Until the jboss-aop-jboss5.deployer has been deployed, these classes use the default/non-aop mc behaviour. Once the jboss-aop=jboss5.deployer has been deployed the AOPJoinpointFactory etc. switch to using the aop behaviour.

                        There is a (so far) basic test in the testsuite under org.jboss.test.aop.test.MicrocontainerJMXUnitTestCase.

                        aop-mc-int-aspect-beans.xml still uses the "verbose" mode of defining the managed aspects:

                         <beanfactory name="JMXAdvice" class="org.jboss.aop.microcontainer.aspects.jmx.JMXIntroduction">
                         <property name="mbeanServer"><inject bean="JMXKernel" property="mbeanServer"/></property>
                         </beanfactory>
                        
                         <bean name="JMXAspect" class="org.jboss.aop.microcontainer.beans.Aspect">
                         <property name="advice"><inject bean="JMXAdvice"/></property>
                         <property name="manager"><inject bean="AspectManager" property="aspectManager"/></property>
                         </bean>
                        
                         <bean name="JMXBinding" class="org.jboss.aop.microcontainer.beans.AspectBinding">
                         <property name="pointcut">execution(* @org.jboss.aop.microcontainer.aspects.jmx.JMX->$implements{org.jboss.kernel.spi.dependency.KernelControllerContextAware}(..))</property>
                         <property name="aspect"><inject bean="JMXAspect" property="definition"/></property>
                         <property name="manager"><inject bean="AspectManager" property="aspectManager"/></property>
                         </bean>
                        


                        Changing this to:
                         <aop:aspect xmlns:aop="urn:jboss:aop-beans:1.0"
                         name="JMXAdvice"
                         class="org.jboss.aop.microcontainer.aspects.jmx.JMXIntroduction"
                         pointcut="execution(* @org.jboss.aop.microcontainer.aspects.jmx.JMX->$implements{org.jboss.kernel.spi.dependency.KernelControllerContextAware}(..))">
                         <property name="mbeanServer"><inject bean="JMXKernel" property="mbeanServer"/></property>
                         </aop:aspect>
                        

                        does not work at present since the AspectBeanMetaDataFactory tries to call AspectManager.instance() before the AspectManager has been deployed, i.e before the dependencies etc have been read. This ties in with http://jira.jboss.com/jira/browse/JBAOP-271 (Hardcoded aspect manager in AspectBeanMetaDataFactory)

                        I am thinking of changing this to be something like:

                         <aop:aspect xmlns:aop="urn:jboss:aop-beans:1.0"
                         name="JMXAdvice"
                         class="org.jboss.aop.microcontainer.aspects.jmx.JMXIntroduction"
                         pointcut="execution(* @org.jboss.aop.microcontainer.aspects.jmx.JMX->$implements{org.jboss.kernel.spi.dependency.KernelControllerContextAware}(..))">
                         <property name="mbeanServer"><inject bean="JMXKernel" property="mbeanServer"/></property>
                         <property name="manager">AspectManager</property>
                         </aop:aspect>
                        


                        where "manager" is a "reserved" property name for this use-case-xml that can be propagated to the created Aspect and AspectBinding beans so that they have the correct dependencies. If the Advice (the top of the three beans in the "verbose" variety) does not have a "manager" property, that should be removed from his metadata.


                        • 9. Re: @JMX aspect and aop/mc integration
                          kabirkhan

                           

                           <beanfactory name="JMXAdvice" class="org.jboss.aop.microcontainer.aspects.jmx.JMXIntroduction">
                           <property name="mbeanServer"><inject bean="JMXKernel" property="mbeanServer"/></property>
                           </beanfactory>
                          
                           <bean name="JMXAspect" class="org.jboss.aop.microcontainer.beans.Aspect">
                           <property name="advice"><inject bean="JMXAdvice"/></property>
                           <property name="manager"><inject bean="AspectManager" property="aspectManager"/></property>
                           </bean>
                          
                           <bean name="JMXBinding" class="org.jboss.aop.microcontainer.beans.AspectBinding">
                           <property name="pointcut">execution(* @org.jboss.aop.microcontainer.aspects.jmx.JMX->$implements{org.jboss.kernel.spi.dependency.KernelControllerContextAware}(..))</property>
                           <property name="aspect"><inject bean="JMXAspect" property="definition"/></property>
                           <property name="manager"><inject bean="AspectManager" property="aspectManager"/></property>
                           </bean>
                          


                          now becomes
                           <aop:aspect xmlns:aop="urn:jboss:aop-beans:1.0"
                           name="JMXAdvice"
                           class="org.jboss.aop.microcontainer.aspects.jmx.JMXIntroduction"
                           manager-bean="AspectManager"
                           manager-property="aspectManager"
                           pointcut="execution(* @org.jboss.aop.microcontainer.aspects.jmx.JMX->$implements{org.jboss.kernel.spi.dependency.KernelControllerContextAware}(..))">
                           <property name="mbeanServer"><inject bean="JMXKernel" property="mbeanServer"/></property>
                           </aop:aspect>
                          


                          • 10. Re: @JMX aspect and aop/mc integration
                            brian.stansberry

                             

                            "kabir.khan@jboss.com" wrote:
                            The AspectManagerService currently has an "exclude" property to set all classes starting with "org.jboss." to not be transformed/inspected, which works on the underlying AspectManager singleton.


                            Tip for anyone trying to convert a JMX microkernel-based service to an MC bean w/ the @JMX annotation -- if you find your bean doesn't get registered in JMX it's probably because of the above exclusion.

                            To get around this, you need to add your class or a containing package to the "include" list in the AspectManager bean, found in deployers/jboss-aop-jboss5.deployer/META-INF/aspect-deployer-beans.xml.

                            To get the services currently in cluster-service.xml registered, I would need to add org.jboss.cache.jmx, org.jboss.cache.pojo.jmx, org.jboss.ha, org.jboss.invocation.jrmp.server.JRMPInvokerHA, org.jboss.invocation.pooled.server.PooledInvokerHA and org.jboss.invocation.unified.server.UnifiedInvokerHA to this list.

                            • 11. Re: @JMX aspect and aop/mc integration
                              brian.stansberry

                              For any bean that calls any method in its constructor, if I add the @JMX annotation I'm getting an NPE during deployment. Typical stack trace follows:

                              2006-11-12 17:02:10,062 ERROR [org.jboss.kernel.plugins.dependency.AbstractKernelController] Error installing to Instantiated: name=UnifiedInvokerHA state=Described
                              java.lang.RuntimeException: java.lang.NullPointerException
                               at org.jboss.aop.proxy.container.GeneratedAOPProxyFactory.getProxy(GeneratedAOPProxyFactory.java:115)
                               at org.jboss.aop.proxy.container.GeneratedAOPProxyFactory.createAdvisedProxy(GeneratedAOPProxyFactory.java:75)
                               at org.jboss.aop.proxy.container.GeneratedAOPProxyFactory.createAdvisedProxy(GeneratedAOPProxyFactory.java:39)
                               at org.jboss.aop.microcontainer.integration.AOPConstructorJoinpoint.dispatch(AOPConstructorJoinpoint.java:82)
                               at org.jboss.kernel.plugins.dependency.KernelControllerContextAction.dispatchJoinPoint(KernelControllerContextAction.java:71)
                               at org.jboss.kernel.plugins.dependency.InstantiateAction.installAction(InstantiateAction.java:52)
                               at org.jboss.kernel.plugins.dependency.KernelControllerContextAction.install(KernelControllerContextAction.java:96)
                               at org.jboss.dependency.plugins.AbstractControllerContextActions.install(AbstractControllerContextActions.java:51)
                               at org.jboss.dependency.plugins.AbstractControllerContext.install(AbstractControllerContext.java:226)
                               at org.jboss.dependency.plugins.AbstractController.install(AbstractController.java:709)
                               at org.jboss.dependency.plugins.AbstractController.incrementState(AbstractController.java:429)
                               at org.jboss.dependency.plugins.AbstractController.resolveContexts(AbstractController.java:538)
                               at org.jboss.dependency.plugins.AbstractController.resolveContexts(AbstractController.java:472)
                               at org.jboss.dependency.plugins.AbstractController.install(AbstractController.java:274)
                               at org.jboss.dependency.plugins.AbstractController.install(AbstractController.java:177)
                               at org.jboss.deployers.plugins.deployers.kernel.BeanMetaDataDeployer.deploy(BeanMetaDataDeployer.java:67)
                               at org.jboss.deployers.plugins.deployers.kernel.BeanMetaDataDeployer.deploy(BeanMetaDataDeployer.java:42)
                               at org.jboss.deployers.plugins.deployers.helpers.AbstractSimpleRealDeployer.deploy(AbstractSimpleRealDeployer.java:53)
                               at org.jboss.deployers.plugins.deployer.AbstractSimpleDeployer.commitDeploy(AbstractSimpleDeployer.java:52)
                               at org.jboss.deployers.plugins.deployer.DeployerWrapper.commitDeploy(DeployerWrapper.java:145)
                               at org.jboss.deployers.plugins.deployment.MainDeployerImpl.commitDeploy(MainDeployerImpl.java:440)
                               at org.jboss.deployers.plugins.deployment.MainDeployerImpl.commitDeploy(MainDeployerImpl.java:451)
                               at org.jboss.deployers.plugins.deployment.MainDeployerImpl.process(MainDeployerImpl.java:381)
                               at org.jboss.system.server.profileservice.ProfileServiceBootstrap.loadProfile(ProfileServiceBootstrap.java:366)
                               at org.jboss.system.server.profileservice.ProfileServiceBootstrap.bootstrap(ProfileServiceBootstrap.java:246)
                               at org.jboss.kernel.plugins.bootstrap.AbstractBootstrap.run(AbstractBootstrap.java:89)
                               at org.jboss.system.server.profileservice.ServerImpl.doStart(ServerImpl.java:401)
                               at org.jboss.system.server.profileservice.ServerImpl.start(ServerImpl.java:340)
                               at org.jboss.Main.boot(Main.java:210)
                               at org.jboss.Main$1.run(Main.java:508)
                               at java.lang.Thread.run(Thread.java:595)
                              Caused by: java.lang.NullPointerException
                               at AOPContainerProxy$4.setSubSystem(AOPContainerProxy$4.java)
                               at org.jboss.invocation.unified.server.UnifiedInvokerHA.<init>(UnifiedInvokerHA.java:50)
                               at AOPContainerProxy$4.<init>(AOPContainerProxy$4.java)
                               at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
                               at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
                               at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
                               at java.lang.reflect.Constructor.newInstance(Constructor.java:494)
                               at java.lang.Class.newInstance0(Class.java:350)
                               at java.lang.Class.newInstance(Class.java:303)
                               at org.jboss.aop.proxy.container.GeneratedAOPProxyFactory.instantiateAndConfigureProxy(GeneratedAOPProxyFactory.java:128)
                               at org.jboss.aop.proxy.container.GeneratedAOPProxyFactory.getProxy(GeneratedAOPProxyFactory.java:111)
                               ... 30 more


                              UnifiedInvokerHA calls its setSubsystem() method in it's constructor.

                              • 12. Re: @JMX aspect and aop/mc integration
                                kabirkhan

                                 

                                "bstansberry@jboss.com" wrote:
                                For any bean that calls any method in its constructor, if I add the @JMX annotation I'm getting an NPE during deployment.


                                I have reproduced the problem and am looking into it

                                • 13. Re: @JMX aspect and aop/mc integration
                                  kabirkhan

                                   

                                  "bstansberry@jboss.com" wrote:
                                  For any bean that calls any method in its constructor, if I add the @JMX annotation I'm getting an NPE during deployment.

                                  This should be fixed now, update jboss-aop-jdk50.jar

                                  • 14. Re: @JMX aspect and aop/mc integration
                                    brian.stansberry

                                    Thanks, that worked. To express my gratitude, here's another one ;-)

                                    Problem now is a bean with a non-default constructor -- the value passed to the c'tor is null if the @JMX annotation is applied. E.g.:

                                    <bean name="HAPartition"
                                     class="org.jboss.ha.framework.server.ClusterPartition">
                                     <annotation>@org.jboss.aop.microcontainer.aspects.jmx.JMX(name="jboss:service=DefaultPartition", exposedInterface=org.jboss.ha.framework.server.ClusterPartitionMBean.class)</annotation>
                                    
                                     .....
                                    
                                    </bean>
                                    
                                    <bean name="DistributedReplicantManager"
                                     class="org.jboss.ha.framework.server.DistributedReplicantManagerImpl">
                                    
                                     <annotation>@org.jboss.aop.microcontainer.aspects.jmx.JMX(name="jboss:service=DistributedReplicantManager,partition=DefaultPartition", exposedInterface=org.jboss.ha.framework.server.DistributedReplicantManagerImplMBean.class)</annotation>
                                    
                                     <constructor>
                                     <parameter class="org.jboss.ha.framework.server.ClusterPartition"><inject name="HAPartition"/></parameter>
                                     </constructor>
                                    
                                    </bean>


                                    Results in:

                                    2006-11-13 15:03:23,906 ERROR [org.jboss.kernel.plugins.dependency.AbstractKernelController] Error installing to Instantiated: name=DistributedReplicantManager state=Described
                                    java.lang.RuntimeException: java.lang.NullPointerException
                                     at org.jboss.aop.proxy.container.GeneratedAOPProxyFactory.getProxy(GeneratedAOPProxyFactory.java:115)
                                     at org.jboss.aop.proxy.container.GeneratedAOPProxyFactory.createAdvisedProxy(GeneratedAOPProxyFactory.java:75)
                                     at org.jboss.aop.proxy.container.GeneratedAOPProxyFactory.createAdvisedProxy(GeneratedAOPProxyFactory.java:39)
                                     at org.jboss.aop.microcontainer.integration.AOPConstructorJoinpoint.dispatch(AOPConstructorJoinpoint.java:82)
                                     at org.jboss.kernel.plugins.dependency.KernelControllerContextAction.dispatchJoinPoint(KernelControllerContextAction.java:71)
                                     at org.jboss.kernel.plugins.dependency.InstantiateAction.installAction(InstantiateAction.java:52)
                                     at org.jboss.kernel.plugins.dependency.KernelControllerContextAction.install(KernelControllerContextAction.java:96)
                                     at org.jboss.dependency.plugins.AbstractControllerContextActions.install(AbstractControllerContextActions.java:51)
                                     at org.jboss.dependency.plugins.AbstractControllerContext.install(AbstractControllerContext.java:226)
                                     at org.jboss.dependency.plugins.AbstractController.install(AbstractController.java:709)
                                     at org.jboss.dependency.plugins.AbstractController.incrementState(AbstractController.java:429)
                                     at org.jboss.dependency.plugins.AbstractController.resolveContexts(AbstractController.java:538)
                                     at org.jboss.dependency.plugins.AbstractController.resolveContexts(AbstractController.java:472)
                                     at org.jboss.dependency.plugins.AbstractController.install(AbstractController.java:274)
                                     at org.jboss.dependency.plugins.AbstractController.install(AbstractController.java:177)
                                     at org.jboss.deployers.plugins.deployers.kernel.BeanMetaDataDeployer.deploy(BeanMetaDataDeployer.java:67)
                                     at org.jboss.deployers.plugins.deployers.kernel.BeanMetaDataDeployer.deploy(BeanMetaDataDeployer.java:42)
                                     at org.jboss.deployers.plugins.deployers.helpers.AbstractSimpleRealDeployer.deploy(AbstractSimpleRealDeployer.java:53)
                                     at org.jboss.deployers.plugins.deployer.AbstractSimpleDeployer.commitDeploy(AbstractSimpleDeployer.java:52)
                                     at org.jboss.deployers.plugins.deployer.DeployerWrapper.commitDeploy(DeployerWrapper.java:145)
                                     at org.jboss.deployers.plugins.deployment.MainDeployerImpl.commitDeploy(MainDeployerImpl.java:440)
                                     at org.jboss.deployers.plugins.deployment.MainDeployerImpl.commitDeploy(MainDeployerImpl.java:451)
                                     at org.jboss.deployers.plugins.deployment.MainDeployerImpl.process(MainDeployerImpl.java:381)
                                     at org.jboss.system.server.profileservice.ProfileServiceBootstrap.loadProfile(ProfileServiceBootstrap.java:366)
                                     at org.jboss.system.server.profileservice.ProfileServiceBootstrap.bootstrap(ProfileServiceBootstrap.java:246)
                                     at org.jboss.kernel.plugins.bootstrap.AbstractBootstrap.run(AbstractBootstrap.java:89)
                                     at org.jboss.system.server.profileservice.ServerImpl.doStart(ServerImpl.java:401)
                                     at org.jboss.system.server.profileservice.ServerImpl.start(ServerImpl.java:340)
                                     at org.jboss.Main.boot(Main.java:210)
                                     at org.jboss.Main$1.run(Main.java:508)
                                     at java.lang.Thread.run(Thread.java:595)
                                    Caused by: java.lang.NullPointerException
                                     at org.jboss.ha.framework.server.DistributedReplicantManagerImpl.<init>(DistributedReplicantManagerImpl.java:114)
                                     at org.jboss.ha.framework.server.DistributedReplicantManagerImpl.<init>(DistributedReplicantManagerImpl.java:99)
                                     at AOPContainerProxy$2.<init>(AOPContainerProxy$2.java)
                                     at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
                                     at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
                                     at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
                                     at java.lang.reflect.Constructor.newInstance(Constructor.java:494)
                                     at java.lang.Class.newInstance0(Class.java:350)
                                     at java.lang.Class.newInstance(Class.java:303)
                                     at org.jboss.aop.proxy.container.GeneratedAOPProxyFactory.instantiateAndConfigureProxy(GeneratedAOPProxyFactory.java:128)
                                     at org.jboss.aop.proxy.container.GeneratedAOPProxyFactory.getProxy(GeneratedAOPProxyFactory.java:111)
                                     ... 30 more


                                    NPE is because the HAPartition ref passed in to the constructor is null. If I remove the @JMX annotation from the DistributedReplicantManager bean, it deploys fine.

                                    1 2 3 Previous Next