11 Replies Latest reply on Feb 2, 2007 6:03 PM by Charles Crouch

    Aspect integration to bootstrap classes

    Scott Stark Master

      Short of moving the AspectManager into the bootstrap-beans.xml, what mechanism do we have to introduce aspects into the bootstrap classes like MainDeployer, and ProfileService?

        • 1. Re: Aspect integration to bootstrap classes
          Scott Stark Master

          The question is should be drop the jboss-aop-mc-int-boot.jar and
          allow for use of aspects in the bootstrap-beans.xml. What I'm needing to
          do is the equivalent of adding these aspects/pointcuts:

           <aspect name="persist"
          class="org.jboss.profileservice.aop.PersistAdvice"/>
           <aspect name="mainDeployer"
          class="org.jboss.profileservice.aop.MainDeployerAdvice"/>
           <bind pointcut="execution(*
          $instanceof{org.jboss.deployers.spi.deployment.MainDeployer}->process(..))">
           <advice name="process" aspect="mainDeployer"/>
           </bind>
           <bind pointcut="execution(*
          $instanceof{org.jboss.managed.api.ManagedProperty}->setValue(..))">
           <advice name="setValue" aspect="persist"/>
           </bind>
          


          Are there aop/mc integration constructs that already allow for this?


          • 2. Re: Aspect integration to bootstrap classes
            Kabir Khan Master

            I think this would have to involve moving aop into the bootstrap, I will take a look first thing tomorrow

            • 3. Re: Aspect integration to bootstrap classes
              Kabir Khan Master

              I am looking at moving the AOP into bootstrap-beans.xml, I will allow for some "initial" XML to be passed in to the aspectmanager bean, which should make possible

               <aspect name="mainDeployer"
              class="org.jboss.profileservice.aop.MainDeployerAdvice"/>
               <bind pointcut="execution(*
              $instanceof{org.jboss.deployers.spi.deployment.MainDeployer}->process(..))">
               <advice name="process" aspect="mainDeployer"/>
               </bind>
              


              However, since AFAICT ManagedProperty is not a bean, in order to be able to do:
               <aspect name="persist"
              class="org.jboss.profileservice.aop.PersistAdvice"/>
               <bind pointcut="execution(*
              $instanceof{org.jboss.deployers.spi.deployment.MainDeployer}->process(..))">
               <advice name="process" aspect="mainDeployer"/>
               </bind>
              


              We have the following choices:
              1) Require jboss to be run with a custom loader for loadtime weaving to be enabled, which might be overkill?
              2) Weave/Prepare ManagedProperty at compiletime, so that it has the AOP hooks in place, and pick up the aspects to be applied to these joinpoints at runtime from the "initial" xml


              • 4. Re: Aspect integration to bootstrap classes
                Scott Stark Master

                Or do what Adrian did in the org.jboss.test.managed.mock.MockTest of the managed project:

                 public void testMock() throws Exception
                 {
                 MockDataSourceManagedObject mock = new MockDataSourceManagedObject();
                
                 ManagedObject mo = WrapperAdvice.wrapManagedObject(mock);
                ...
                
                package org.jboss.managed.plugins.advice;
                
                import java.util.Set;
                
                import org.jboss.aop.joinpoint.Invocation;
                import org.jboss.aop.proxy.container.AOPProxyFactoryParameters;
                import org.jboss.aop.proxy.container.GeneratedAOPProxyFactory;
                import org.jboss.logging.Logger;
                import org.jboss.managed.api.Fields;
                import org.jboss.managed.api.ManagedObject;
                import org.jboss.managed.api.ManagedProperty;
                
                /**
                 * WrapperAdvice, intercepts methods that produce objects
                 * that require proxies.
                 *
                 * @author <a href="adrian@jboss.com">Adrian Brock</a>
                 * @version $Revision: 59258 $
                 */
                public class WrapperAdvice
                {
                 private static Logger log = Logger.getLogger(WrapperAdvice.class);
                
                 /**
                 * Wrap a managed object
                 *
                 * @param managedObject the managed object
                 * @return the managed object wrapper
                 */
                 public static ManagedObject wrapManagedObject(ManagedObject managedObject)
                 {
                 return createProxy(managedObject, ManagedObject.class);
                 }
                
                 /**
                 * Wrap a managed property
                 *
                 * @param managedProperty the managed property
                 * @return the managed property wrapper
                 */
                 public static ManagedProperty wrapManagedProperty(ManagedProperty managedProperty)
                 {
                 return createProxy(managedProperty, ManagedProperty.class);
                 }
                
                 /**
                 * Wrap fields
                 *
                 * @param fields the fields
                 * @return the fields wrapper
                 */
                 public static Fields wrapFields(Fields fields)
                 {
                 return createProxy(fields, Fields.class);
                 }
                
                 /**
                 * Wrap a returned managed object
                 *
                 * @param invocation the invocation
                 * @return the wrapped managed object
                 * @throws Throwable for any error
                 */
                 public ManagedObject wrapManagedObject(Invocation invocation) throws Throwable
                 {
                 ManagedObject result = (ManagedObject) invocation.invokeNext();
                 return wrapManagedObject(result);
                 }
                
                 /**
                 * Wrap a returned managed property
                 *
                 * @param invocation the invocation
                 * @return the wrapped managed property
                 * @throws Throwable for any error
                 */
                 public ManagedProperty wrapManagedProperty(Invocation invocation) throws Throwable
                 {
                 ManagedProperty result = (ManagedProperty) invocation.invokeNext();
                 return wrapManagedProperty(result);
                 }
                
                 /**
                 * Wrap a returned managed property set
                 *
                 * @param invocation the invocation
                 * @return the wrapped managed property set
                 * @throws Throwable for any error
                 */
                 @SuppressWarnings("unchecked")
                 public Set<ManagedProperty> wrapManagedPropertySet(Invocation invocation) throws Throwable
                 {
                 Set<ManagedProperty> result = (Set<ManagedProperty>) invocation.invokeNext();
                 return new WrapperSet<ManagedProperty>(result, ManagedProperty.class);
                 }
                
                 /**
                 * Wrap fields
                 *
                 * @param invocation the invocation
                 * @return the wrapped managed property
                 * @throws Throwable for any error
                 */
                 public Fields wrapFields(Invocation invocation) throws Throwable
                 {
                 Fields result = (Fields) invocation.invokeNext();
                 return wrapFields(result);
                 }
                
                 /**
                 * Create a proxy
                 *
                 * @param <T> the expected type
                 * @param target the target
                 * @param interfaceClass the interface class
                 * @return the proxy
                 */
                 static <T> T createProxy(T target, Class<T> interfaceClass)
                 {
                 if (target == null)
                 return null;
                
                 GeneratedAOPProxyFactory proxyFactory = new GeneratedAOPProxyFactory();
                 AOPProxyFactoryParameters params = new AOPProxyFactoryParameters();
                 params.setInterfaces(new Class[] { interfaceClass });
                 params.setObjectAsSuperClass(true);
                 params.setTarget(target);
                 Object proxy = proxyFactory.createAdvisedProxy(params);
                 if( log.isTraceEnabled() )
                 log.trace("Created proxy: "+proxy.getClass()+"@"+System.identityHashCode(proxy)+" target: "+target.getClass());
                 return interfaceClass.cast(proxy);
                 }
                }
                
                


                which uses the WrapperAdvice to bootstrap a aop proxy so that subsequent access to the ManagedProperty are proxied. This is what I was planning on using in the ManagedObjectBuilder that created the top-level MnagedObject of a deployment.

                This works right?


                • 5. Re: Aspect integration to bootstrap classes
                  Kabir Khan Master

                  Ah yes, how could I forget about the proxies I helped implement :-) I'll have a look at where the managed object are created and try to fit them in

                  • 6. Re: Aspect integration to bootstrap classes
                    Kabir Khan Master

                    I have completed the first part of this, so that we get a proxy created for the MainDeployer. The AspectManager and AspectDeployer are now created in bootstrap-beans.xml, and I have moved these to the jboss/lib directory:
                    -jboss-aop-jdk50.jar
                    -jboss-aop-mc-int.jar
                    -trove.jar
                    -javassist.jar (was there already)
                    -jboss-aop-deployer-jdk50.jar (The parts of the jboss-aspect-library.jar relating to deployment, i.e. org.jboss.aop.deployers and org.jboss.aop.deployment)

                    The bootstrap-beans.xml initialises the AspectManager with the necessary aop.xml so that this is available when the MainDeployer is instantiated, so that we get a proxy created for that.

                    I have kept the jboss-aop-jboss5.deployer, it now contains a bean called "AspectLibrary" whose job is to deploy the base-aspects.xml (containing the @SecurityDomain, @Tx etc. interceptors) and the old aspect library (minus the stuff that now lives in jboss-aop-deployer-jdk50.jar). Services that previously depended on the AspectDeployer, and which need the aspect library aspects, should now depend on the "AspectLibrary", I have updated EJB 3 to do this.

                    I have created some stupid implementations of org.jboss.profileservice.aop.MainDeployerAspect and org.jboss.profileservice.aop.PersistAspect in the system module to verify that things work. MainDeployerAspect is functional, and I will look at the PersistAspect/ManagedProperty part tomorrow.

                    • 7. Re: Aspect integration to bootstrap classes
                      Kabir Khan Master

                      The aop-mc-int project no longer creates
                      lib/jboss-aop-mc-int-boot.jar
                      lib/jboss-aop-mc-int-deployer.jar

                      and I have removed these files from the 3rdparty repository

                      • 8. Re: Aspect integration to bootstrap classes
                        Charles Crouch Expert

                         

                        "kabir.khan@jboss.com" wrote:
                        The aop-mc-int project no longer creates
                        lib/jboss-aop-mc-int-boot.jar
                        lib/jboss-aop-mc-int-deployer.jar

                        and I have removed these files from the 3rdparty repository


                        I just got an *entirely* clean checkout of /trunk (r60207), and am now getting this when I ./build/build.bat

                        BUILD FAILED
                        C:\usr\projects\current\jboss\trunk\embedded\build.xml:330: problem opening C:\usr\projects\current\jboss\trunk\thirdparty\jboss\microcontainer\lib\jboss-aop-mc-int-boot.jar
                        


                        • 9. Re: Aspect integration to bootstrap classes
                          Kabir Khan Master

                          I've fixed and commited this. Am doing a
                          $build clean main

                          to check for any other issues

                          • 10. Re: Aspect integration to bootstrap classes
                            Kabir Khan Master

                            Should be fine now (I had to commit the embedded/build.xml again)

                            • 11. Re: Aspect integration to bootstrap classes
                              Charles Crouch Expert

                              r60223 compile great, thanks.