3 Replies Latest reply on Jan 26, 2010 3:19 PM by kabirkhan

    Problem with AOP arond advice in JBoss trunk

    adinn

      I have been trying to revive on AS trunk the Web Service Transactions BAFramework demo which we last had working on AS 4.2.3. In doing so  have come across what appears to be a problem with AOP. I don't have a _simple_ test case yet but by playing around with the code I have pinned the problem down.

       

      My AOP advice binding is not being applied in a specific circumstance. This happens when the method belongs to an EJB and is annotated with a WebMethod annotation. In this case if I annotate the method with the BAMethod annotation AOP fails to apply the advice binding it. However, if I move the BAMethod annotation to a submethod called by the WebMethod then AOP respects the binding. Here, in brief, are the details of the failing and working cases:

       

      This is the jboss-aop.xml

       

      <aop xmlns="urn:jboss:aop-beans:1.0">

       

          <!-- BA Processing Aspect -->
          <aspect class="org.jboss.jbossts.baframework.aspect.TransactionProcessingAspect" scope="PER_INSTANCE"/>

       

          <pointcut name="baMethodAnnotation" expr="execution(* *->@org.jboss.jbossts.baframework.annotation.BAMethod(..))"/>

       

          <pointcut name="baDataManagementAnnotation" expr="field(org.jboss.jbossts.baframework.datamgmt.DataManager *->@org.jboss.jbossts.baframework.annotation.BADataManagement)"/>

       

          <bind pointcut="baMethodAnnotation">
              <advice name="process" aspect="org.jboss.jbossts.baframework.aspect.TransactionProcessingAspect"/>
          </bind>

       

          <bind pointcut="baDataManagementAnnotation">
              <advice name="access" aspect="org.jboss.jbossts.baframework.aspect.TransactionProcessingAspect"/>
          </bind>
      </aop>

       

      n.b. teh aspect class, TransactionProcessingAspect, implements methdos with the following signatures:

       

          public Object process(MethodInvocation invocation) throws Throwable;
          public Object access(FieldReadInvocation invocation) throws Throwable;
          public Object access(FieldWriteInvocation invocation) throws Throwable;

       

      Here is the web service implementation class te aspect should be applied to

       

      @Stateless
      @Remote(Hotel.class)
      @WebService(name="Hotel")
      @SOAPBinding(style = SOAPBinding.Style.RPC)
      @HandlerChain(file = "jaxws-handlers-server.xml")
      @BAService(serviceClass=HotelImpl.class,ejbInterface=Hotel.class,jndiName="bademo/HotelImpl/remote")
      public class HotelImpl implements Hotel
      {
          . . .
          @WebMethod
          @BAMethod(agreement=AgreementType.PARTICIPANT_COMPLETION)
          @BACompensatedBy(value="cancelRoom",type=DataMatch.CUSTOM)
          @BAResult("reservationNumber")
          public Integer bookRoom(@BAParam("username")String username,@BAParam("password")String password, Integer roomNumber)
                  throws HotelCustomException, RoomAlreadyOccupiedException
          {
              log.info("bookRoom()");
              hotelView.newMethod("bookRoom()");
              hotelView.addMessage("Username: " + username);
          . . .

       

      This version of the code builds and boots up ok but AOP fails to call the aspect class's advice method, process(MethodInvocation invocation)

       

      However, if I introduce an auxiliary method so that the web service target method becomes a wrapper and then split the annotations, applying the @WebMethod to the wrapper and the @BAMethod annotation to the auxiliary method, then my advice method does get called.

       

          @WebMethod
          public Integer bookRoom(String username, String password, Integer roomNumber)
                  throws HotelCustomException, RoomAlreadyOccupiedException
          {
              return bookRoomInternal(username, password, roomNumber);
          }

       

          @BAMethod(agreement=AgreementType.PARTICIPANT_COMPLETION)
          @BACompensatedBy(value="cancelRoom",type=DataMatch.CUSTOM)
          @BAResult("reservationNumber")
          public Integer bookRoomInternal(@BAParam("username")String username,@BAParam("password")String password, Integer roomNumber)
                  throws HotelCustomException, RoomAlreadyOccupiedException
          {
              log.info("bookRoom()");
              hotelView.newMethod("bookRoom()");
              hotelView.addMessage("Username: " + username);
          . . .

       

      Any idea why AOP does not call process when both annotations  are applied tot he service method?

       

      If you need the full source I can provide it but it's a bit large and messy as it involves EJB, Web Servces and XTS (BA) code as well as the aspect code sketched above. I was hoping this description might be enough to allow you to identify what is wrong.

       

      n.b. I am doing the AOP transform offline but I encountered the same failure using dynamic AOP. I have not yet seen whether inserting the auxiliary method fixes the dynamic AOP case.

       

      regards,

       


      Andrew Dinn

        • 1. Re: Problem with AOP arond advice in JBoss trunk
          jaikiran

          Not sure, but maybe related to this https://jira.jboss.org/jira/browse/EJBTHREE-1950 (and the related JBPAPP issue). But that issue is fixed in the version that's currently in AS trunk.

          • 2. Re: Problem with AOP arond advice in JBoss trunk
            adinn
            jaikiran wrote:

             

            Not sure, but maybe related to this https://jira.jboss.org/jira/browse/EJBTHREE-1950 (and the related JBPAPP issue). But that issue is fixed in the version that's currently in AS trunk.

             

            Hmm, that looks interesting. I wonder if it is the same EJB bug crawling out of the woodwork or whether it is the processing of the WebService annotation which is causing the BAMethod annotations to go AWOL in the same way as happened for @Remote? Perhaps Carlo or Alessio might know?

            • 3. Re: Problem with AOP arond advice in JBoss trunk
              kabirkhan

              I am looking into some failures with scoped aop and wars and found this, which I have posted to dev list. If my fix is correct I'll commit that tomorrow

               

              -------------

               

              Subject: Re: [jboss-dev] WarAnnotationMetaDataDeployer and AOP failures

              From: Kabir Khan <kabir.khan@jboss.com>

              Date: 26 January 2010 20:17:26 GMT

              To: JBoss.org development list <jboss-development@lists.jboss.org>

               

              The AOP deployer has AopMetaDataDeployerOutput.class as an output, so I added that to the WarAnnotationMetaDataDeployer as an input. Is that the right way?
              On 26 Jan 2010, at 18:39, Kabir Khan wrote:

              Flavia and I are debugging the scoped AOP test failures in AS and have found something odd going on when deploying an ear with a war with classes. Basically WarAnnotationMetaDataDeployer loads all the classes  in the war [1] before the AOPDeploymentAopMetaDataDeployer has the chance to add the bindings to the aspect manager [2]. This means that the classes in the war are loaded before the bindings are added, so they do not get woven. The deployers are in the same deployer stage POST_CLASSLOADER, what is the best way to change their orders around?

              [1]
              Daemon System Thread [RMI TCP Connection(6)-127.0.0.1] (Suspended (breakpoint at line 69 in SuperClassesFirstWeavingStrategy))
              SuperClassesFirstWeavingStrategy.translate(AspectManager, String, ClassLoader, byte[]) line: 69
              ScopedVFSClassLoaderDomain(AspectManager).translate(String, ClassLoader, byte[]) line: 1071
              ScopedVFSClassLoaderDomain(AspectManager).transform(ClassLoader, String, Class, ProtectionDomain, byte[]) line: 1015
              AOPTransformer.aspectTransform(String, ClassLoader, Class<?>, ProtectionDomain, byte[]) line: 87
              AOPTransformer.transform(ClassLoader, String, Class<?>, ProtectionDomain, byte[]) line: 75
              TransformerManager.transform(ClassLoader, String, Class, ProtectionDomain, byte[]) line: 169
              InstrumentationImpl.transform(ClassLoader, String, Class, ProtectionDomain, byte[], boolean) line: 365
              ClassLoader.defineClass1(String, byte[], int, int, ProtectionDomain, String) line: not available [native method]
              BaseClassLoader(ClassLoader).defineClass(String, byte[], int, int, ProtectionDomain) line: 698
              BaseClassLoader.access$200(BaseClassLoader, String, byte[], int, int, ProtectionDomain) line: 64
              BaseClassLoader$2.run() line: 577
              BaseClassLoader$2.run() line: 537
              AccessController.doPrivileged(PrivilegedAction<T>, AccessControlContext) line: not available [native method]
              BaseClassLoader.loadClassLocally(String, boolean) line: 535
              BaseClassLoader.loadClassLocally(String) line: 512
              FilteredDelegateLoader(BaseDelegateLoader).loadClass(String) line: 134
              FilteredDelegateLoader.loadClass(String) line: 131
              ClassLoadingTask$ThreadTask.run() line: 455
              ClassLoaderManager.nextTask(Thread, ClassLoadingTask) line: 267
              ClassLoaderManager.process(Thread, ClassLoadingTask) line: 166
              ClassLoaderDomain(BaseClassLoaderDomain).loadClass(BaseClassLoader, String, boolean) line: 265
              ClassLoaderDomain(BaseClassLoaderDomain).loadClass(BaseClassLoader, String) line: 1124
              BaseClassLoader.loadClassFromDomain(String, boolean) line: 805
              BaseClassLoader.loadClass(String, boolean) line: 445
              BaseClassLoader(ClassLoader).loadClass(String) line: 250
              AnnotatedClassFilter.accepts(VirtualFile) line: 121
              AnnotatedClassFilter.visit(VirtualFile) line: 102
              WrappingVirtualFileHandlerVisitor.visit(VirtualFileHandler) line: 62
              FileSystemContext(AbstractVFSContext).visit(VirtualFileHandler, VirtualFileHandlerVisitor, boolean, boolean, boolean, boolean, VirtualFileFilter) line: 362
              FileSystemContext(AbstractVFSContext).visit(VirtualFileHandler, VirtualFileHandlerVisitor, boolean, boolean, boolean, boolean, VirtualFileFilter) line: 374
              FileSystemContext(AbstractVFSContext).visit(VirtualFileHandler, VirtualFileHandlerVisitor, boolean, boolean, boolean, boolean, VirtualFileFilter) line: 374
              FileSystemContext(AbstractVFSContext).visit(VirtualFileHandler, VirtualFileHandlerVisitor, boolean, boolean, boolean, boolean, VirtualFileFilter) line: 374
              FileSystemContext(AbstractVFSContext).visit(VirtualFileHandler, VirtualFileHandlerVisitor, boolean, boolean, boolean, boolean, VirtualFileFilter) line: 374
              FileSystemContext(AbstractVFSContext).visit(VirtualFileHandler, VirtualFileHandlerVisitor, boolean, boolean, boolean, boolean, VirtualFileFilter) line: 374
              FileSystemContext(AbstractVFSContext).visit(VirtualFileHandler, VirtualFileHandlerVisitor, boolean, boolean, boolean, boolean, VirtualFileFilter) line: 374
              FileSystemContext(AbstractVFSContext).visit(VirtualFileHandler, VirtualFileHandlerVisitor) line: 307
              VFS.visit(VirtualFile, VirtualFileVisitor) line: 438
              VirtualFile.visit(VirtualFileVisitor) line: 448
              WarAnnotationMetaDataDeployer.getClasses(VFSDeploymentUnit, VirtualFile) line: 172
              WarAnnotationMetaDataDeployer.processMetaData(VFSDeploymentUnit, List<VirtualFile>) line: 146
              WarAnnotationMetaDataDeployer.deploy(VFSDeploymentUnit) line: 125
              WarAnnotationMetaDataDeployer.deploy(DeploymentUnit) line: 78
              DeployerWrapper.deploy(DeploymentUnit) line: 179
              DeployersImpl.doDeploy(Deployer, DeploymentUnit) line: 1660
              DeployersImpl.doInstallParentFirst(Deployer, DeploymentContext) line: 1378
              DeployersImpl.doInstallParentFirst(Deployer, DeploymentContext) line: 1431
              DeployersImpl.install(ControllerContext, ControllerState, ControllerState) line: 1319
              DeploymentControllerContext(AbstractControllerContext).install(ControllerState, ControllerState) line: 378
              AbstractKernelController(AbstractController).install(ControllerContext, ControllerState, ControllerState) line: 1890
              AbstractKernelController(AbstractController).incrementState(ControllerContext, boolean) line: 1019
              AbstractKernelController(AbstractController).executeOrIncrementStateDirectly(ControllerContext, boolean) line: 1251
              AbstractKernelController(AbstractController).resolveContexts(ControllerState, ControllerState, boolean) line: 1175
              AbstractKernelController(AbstractController).resolveContexts(boolean) line: 1073
              AbstractKernelController(AbstractController).change(ControllerContext, ControllerState, boolean) line: 887
              AbstractKernelController(AbstractController).change(ControllerContext, ControllerState) line: 602
              DeployersImpl.process(List<DeploymentContext>, List<DeploymentContext>) line: 898
              MainDeployerImpl.process() line: 677
              MainDeployer.deploy(URL) line: 370
              MainDeployer.redeploy(URL) line: 277


              [2]
              Daemon System Thread [RMI TCP Connection(6)-127.0.0.1] (Suspended (breakpoint at line 146 in AspectBinding))
              AspectBinding.start() line: 146
              GeneratedMethodAccessor192.invoke(Object, Object[]) line: not available
              DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: 25
              Method.invoke(Object, Object...) line: 597
              ReflectionUtils.invoke(Method, Object, Object[]) line: 59
              ReflectMethodInfoImpl.invoke(Object, Object[]) line: 151
              BasicMethodJoinPoint.dispatch() line: 66
              KernelControllerContextAction$JoinpointDispatchWrapper.execute() line: 257
              KernelControllerContextAction$JoinpointDispatchWrapper(ExecutionWrapper).execute(AccessControlContext) line: 47
              KernelControllerContextAction.dispatchExecutionWrapper(KernelControllerContext, ExecutionWrapper) line: 125
              KernelControllerContextAction.dispatchJoinPoint(KernelControllerContext, Joinpoint) line: 72
              StartStopLifecycleAction(LifecycleAction).installActionInternal(KernelControllerContext) line: 202
              StartStopLifecycleAction(InstallsAwareAction).installAction(KernelControllerContext) line: 54
              StartStopLifecycleAction(InstallsAwareAction).installAction(ControllerContext) line: 42
              StartStopLifecycleAction(SimpleControllerContextAction<T>).simpleInstallAction(T) line: 62
              StartStopLifecycleAction(AccessControllerContextAction<S,T>).install(ControllerContext) line: 71
              KernelControllerContextActions(AbstractControllerContextActions).install(ControllerContext, ControllerState, ControllerState) line: 51
              AbstractKernelControllerContext(AbstractControllerContext).install(ControllerState, ControllerState) line: 378
              ScopedKernelController(AbstractController).install(ControllerContext, ControllerState, ControllerState) line: 1890
              ScopedKernelController(AbstractController).incrementState(ControllerContext, boolean) line: 1019
              ScopedKernelController(AbstractController).executeOrIncrementStateDirectly(ControllerContext, boolean) line: 1251
              ScopedKernelController(AbstractController).resolveContexts(ControllerState, ControllerState, boolean) line: 1175
              ScopedKernelController(AbstractController).resolveContexts(boolean) line: 1073
              AbstractKernelController(AbstractController).resolveContexts(boolean) line: 1104
              AbstractKernelController(AbstractController).install(ControllerContext, boolean) line: 842
              AbstractKernelController(AbstractController).install(ControllerContext) line: 589
              AbstractAopMetaDataDeployer$MyBeanMetaDataDeployer.deploy(FakeComponentUnit, BeanMetaData) line: 363
              AbstractAopMetaDataDeployer$MyBeanMetaDataDeployer.access$100(AbstractAopMetaDataDeployer$MyBeanMetaDataDeployer, FakeComponentUnit, BeanMetaData) line: 329
              AOPDeploymentAopMetaDataDeployer(AbstractAopMetaDataDeployer<T>).deployBeans(VFSDeploymentUnit, AopMetaDataDeployerOutput) line: 269
              AOPDeploymentAopMetaDataDeployer(AbstractAopMetaDataDeployer<T>).deploy(VFSDeploymentUnit, T) line: 133
              AOPDeploymentAopMetaDataDeployer.deploy(VFSDeploymentUnit, AOPDeployment) line: 46
              AOPDeploymentAopMetaDataDeployer.deploy(VFSDeploymentUnit, Object) line: 36
              AOPDeploymentAopMetaDataDeployer(AbstractSimpleVFSRealDeployer<T>).deploy(DeploymentUnit, T) line: 56
              AOPDeploymentAopMetaDataDeployer(AbstractSimpleRealDeployer<T>).internalDeploy(DeploymentUnit) line: 62
              AOPDeploymentAopMetaDataDeployer(AbstractRealDeployer).deploy(DeploymentUnit) line: 55
              DeployerWrapper.deploy(DeploymentUnit) line: 179
              DeployersImpl.doDeploy(Deployer, DeploymentUnit) line: 1660
              DeployersImpl.doInstallParentFirst(Deployer, DeploymentContext) line: 1378
              DeployersImpl.doInstallParentFirst(Deployer, DeploymentContext) line: 1431
              DeployersImpl.install(ControllerContext, ControllerState, ControllerState) line: 1319
              DeploymentControllerContext(AbstractControllerContext).install(ControllerState, ControllerState) line: 378
              AbstractKernelController(AbstractController).install(ControllerContext, ControllerState, ControllerState) line: 1890
              AbstractKernelController(AbstractController).incrementState(ControllerContext, boolean) line: 1019
              AbstractKernelController(AbstractController).executeOrIncrementStateDirectly(ControllerContext, boolean) line: 1251
              AbstractKernelController(AbstractController).resolveContexts(ControllerState, ControllerState, boolean) line: 1175
              AbstractKernelController(AbstractController).resolveContexts(boolean) line: 1073
              AbstractKernelController(AbstractController).change(ControllerContext, ControllerState, boolean) line: 887
              AbstractKernelController(AbstractController).change(ControllerContext, ControllerState) line: 602
              DeployersImpl.process(List<DeploymentContext>, List<DeploymentContext>) line: 898
              MainDeployerImpl.process() line: 677
              MainDeployer.deploy(URL) line: 370
              MainDeployer.redeploy(URL) line: 277


              _______________________________________________
              jboss-development mailing list
              jboss-development@lists.jboss.org
              https://lists.jboss.org/mailman/listinfo/jboss-development