small refactr logo
At refactr we believe in the value of connection, the utility of agile processes, and the power of great ideas. We are creating the next generation of software for people who expect more from their web applications.
refactr
« RSS has died on the vine. | Success with AOP in Grails 1.1 »


Problems with AOP in Grails 1.1


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"
               }
       }
}

This entry was posted by Scott Vlaminck on Friday, May 15th, 2009 at 12:15 pm and is filed under Agile Processes. You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site.

Further Discussion (4 Responses so far. Add yours)

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

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

  3. Chad Small said...
    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. Scott Vlaminck said...
    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.

Join the Discussion