2

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 {
  ...
  ...
}
Eric B.
  • 23,425
  • 50
  • 169
  • 316

1 Answers1

0

From AspectJ documentation:

AspectJ 5 allows aspects and their members to be specified using either the code style or the annotation style. Whichever style you use, the AspectJ weaver ensures that your program has exactly the same semantics. It is, to quote a famous advertising campaign, "a choice, not a compromise". The two styles can be mixed within a single application, and even within a single source file, though we doubt this latter mix will be recommended in practice.

Reading it I think is not a problem about mix pointcut style, but I think it's worth try to change this aspect to code style instead annotation way.

Other thing to try is change the package location of RequiredUserDetailsAspect. This include to move into src/main/java insteado of src/test/java (I can rememberer a problem of double wave on of test folder on Roo when a precedence is declared).

Good luck!

jmvivo
  • 2,653
  • 1
  • 16
  • 20