Problems with AOP in Grails 1.1

Post by Scott Vlaminck

I’m trying to get AOP working in Grails 1.1 and running into some problems. I’m sure I’m just doing something simple wrong, due to my lack of experience with Spring AOP. My problem is that I can’t seem to get ‘around advice’ working on a Grails Service. I get no error, but my aspect is not invoked.

To simplify everything, I created a Hello World app that does almost nothing: my controller calls my service and both print log messages. The service implements an interface as described in a couple posts to the grails user email list (the interface is defined in src/groovy). And my aspect just logs before and after the method invocation (the aspect is defined in grails-app/utils).

I’ve tried a number of different ways of configuring the aspect in resources.groovy (in grails-app/conf/spring), but nothing seems to change (except I do get errors on startup if I define the aspect incorrectly in resources.groovy). I’ve even tried defining my Service and interface in the default package and in their own package.

Again, since this is my first attempt to use Spring AOP, I figure that I must be missing something simple. I uploaded my hello world app to google code if anyone is interested in downloading and running the app.

Anyone with ideas where to look? The relevant bits of my app are included below as well.

Service:

public class TheService implements TheServiceInterface {
       def service(Integer i) {
               log.debug "TheService.service(${i})"
               println "TheService.service(${i})"
               return "Hello world"
       }
}

Aspect:

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;

public class TheAspect implements MethodInterceptor {
   public Object invoke(MethodInvocation method) throws Throwable
       {
       log.debug("Before Invoking Method");
       println("Before Invoking Method");

       Object val = method.proceed();

       log.debug("After Invoking Method");
       println("After Invoking Method");

       return val + "updated value";
   }

 // not sure if this method is necessary or even doing anything
   public Object invoke(MethodInvocation method, Integer i) throws Throwable {
       log.debug("Before Invoking Method with ${i}");
       println("Before Invoking Method with ${i}");

       Object val = method.proceed();

       log.debug("After Invoking Method with ${i}");
       println("After Invoking Method with ${i}");

       return val + "updated value";
   }
}

I’ve tried a number of different config changes in resources.groovy (one at a time). Below are two versions that seem like they should each work.

conf/spring/resources.groovy:

theAspect(TheAspect)

// config version 1
aop {
       config {
               aspect(ref:"theAspect") {
                       pointcut id:"thePointcut", expression:"execution(*
TheServiceInterface.service(Integer)) && args(i)"
                       around 'pointcut-ref':"thePointcut", method:"invoke", 'arg-names':"i"
               }
       }
}

// config version 2
aop {
       config("proxy-target-class":true) {
               aspect(id:"theAspectId", ref:"theAspect" ) {
                       around method:"invoke", pointcut: "execution(*
TheServiceInterface.service(Integer)) && args(i)", 'arg-names':"i"
               }
       }
}

About Scott Vlaminck

believes software development is more about people than technology; believes in agile processes; software developer, engineer, designer, architect, or whatever they're calling us these days; enjoys discussing software design; working on a program to write other programs (but it hasn't written itself yet).
This entry was posted in Agile Processes. Bookmark the permalink.

You may also like:

4 Responses to Problems with AOP in Grails 1.1

  1. Graeme Rocher says:

    If you look at BeanBuilderTests in the Grails codebase there is an example of using Spring AOP. See testUseSpringNamespaceAsMethod()

  2. Thanks, Graeme. It helps to see it in action. I’ll take a look.

  3. Chad Small says:

    I took a quick look Scott and I didn’t see anything that jumped out based on Graeme’s unit test reference – which didn’t include args like your example. I’ll be curious how this plays out.

  4. Thanks for taking the time, Chad. I just got things working this weekend. I’ve just put together another post explaining the changes I made.

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>