Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [aspectj-users] Why is my pointcut not advising methods declared in a another aspect?

I presume all these aspects are being compiled together with the code. You shouldn't have to worry about that order the aspects are applied in - yes there are ITDs but the weaver considers the system as a whole and will apply the aspects to ITD'd methods as well as existing methods:

public class Code {
  public void moo(String s) {}
}

aspect X {
  public void Code.boo(String s) {}
}

aspect Y {
  before(): execution(* *(String)) {}
}

> ajc -showWeaveInfo Code.java X.java Y.java

Join point 'method-execution(void Code.boo(java.lang.String))' in Type 'X' (X.java:2) advised by before advice from 'Y' (Y.java:2)
Type 'Code' (Code.java) has intertyped method from 'X' (X.java:'void Code.boo(java.lang.String)')
Join point 'method-execution(void Code.moo(java.lang.String))' in Type 'Code' (Code.java:2) advised by before advice from 'Y' (Y.java:2)

Precedence only affects advice, not ITDs. The advice is being applied to the ITDs, not to what you imagine is happening under the covers (the methods being stuffed into the target, hence you think you need to get that done first). All ITDs (and declares) are processed to ensure the type system is coherent and then the advice is applied.

I feel like we used to have problems in this area but I thought they were all fixed up.  Worth raising an AspectJ issue. If you can provide a simple test case that shows it failing (unlike mine which shows it working) that would be really useful.  Maybe if any of the annotations you are triggering on are being applied by declare, try putting them directly on the methods of interest and temporarily removing the declare - does that make a difference. It may be the interplay between declare/itd and advice.

cheers,
Andy



On 3 April 2014 18:37, Eric B <ebenzacar@xxxxxxxxx> wrote:
I'm using Roo and Compile Time Weaving for my application.  One of the classes that Roo has generated is my `UserIntegrationTest`:

    @RooIntegrationTest(entity = User.class)
    @WebAppConfiguration
    @ActiveProfiles("test")
    @DirtiesContext
    @RequiredUserDetails(roles=Role.ROOT)
    public class UserIntegrationTest {
    @Test
    public void myTestMethod(){
   
    }
    }


Most of the code is all in the Roo generated ITD:

    privileged aspect UserIntegrationTest_Roo_IntegrationTest {
        
        declare @type: UserIntegrationTest: @RunWith(SpringJUnit4ClassRunner.class);
        
        declare @type: UserIntegrationTest: @ContextConfiguration(locations = "classpath*:/META-INF/spring/applicationContext*.xml");
        
        declare @type: UserIntegrationTest: @Transactional;
        
        @Autowired
        UserDataOnDemand UserIntegrationTest.dod;
        
        @Autowired
        UserService UserIntegrationTest.userService;
        
        @Autowired
        UserRepository UserIntegrationTest.userRepository;
        
        @Test
        public void UserIntegrationTest.testCountAllUsers() {
            Assert.assertNotNull("Data on demand for 'User' failed to initialize correctly", dod.getRandomUser());
            long count = userService.countAllUsers();
            Assert.assertTrue("Counter for 'User' incorrectly reported there were no entries", count > 0);
        }

        ...
        ...
        ...

    }


I've written my own aspect to handle my `@RequiredUserDetails` annotation.  My pointcut specifies any `@Test` method in a class that is annotated with `@RequiredUserDetails`.  Although the pointcut works fine for any methods declared in the main class (ie: `MyTestMethod()`), it does not pick up any of the methods in the ITD.  

    @Aspect
    public class RequiredUserDetailsAspect {
    /**
    * Defines any public <code>@Test</code> method
    */
    @Pointcut("execution(public * *(..)) && @annotation(org.junit.Test)")
    public void testMethod() {};
   
    /**
    * Anything with the {@link RequiredUserDetails} annotation on the method
    */
    @Pointcut("@annotation(RequiredUserDetails)")
    public void annotatedMethod(){};
   
    /**
    * Anything with the {@link RequiredUserDetails} annotation on the class
    */
    @Pointcut("@within(RequiredUserDetails)")
    public void annotatedClass(){};
   

    @Before("testMethod() && (annotatedClass() || annotatedMethod())")
    public void authenticateUser(JoinPoint jp){
    // check for any class annotations
            }
    }


I would have expected that given Roo ITDs are being CTW, my aspect would apply to those methods as well.  I am presuming that my aspect is woven before the Roo aspect and consequently doesn't see Roo's ITDs as part of my class.  

Is there a way to either ensure that Roo's ITDs are woven before my own aspects or to ensure that my pointcut applies to the Roo ITDs as well?

I've tried adding `@DeclarePrecedence` to the top of the aspect, but either it is not working as I hoped, or I have it defined incorrectly as it has made no difference.

    @Aspect
    @DeclarePrecedence("**.*Roo*, RequiredUserDetailsAspect")
    public class RequiredUserDetailsAspect {
      ...
      ...
    }


Thanks!

Eric


_______________________________________________
aspectj-users mailing list
aspectj-users@xxxxxxxxxxx
https://dev.eclipse.org/mailman/listinfo/aspectj-users



Back to the top