Tuesday, March 30, 2010

Grails: Intercepting Service class methods - part 3

Well - I have a couple of updates to my previous post:

1) Grails 1.2.2 is out and it does look like the Spring DSL for AOP definitions is fixed.
2) using the Spring xml definition in part 2 performed very poorly. I am not sure why but if I changed the pointcut definition to:

pointcut="execution(* com.redpointtech.flex..*Service..*(..))"


it performed MUCH better

Given that the DSL is fixed and I needed it to perform better I have changed the AOP definition again to the following in the resources.groovy file.

 beans = {  
xmlns aop:"http://www.springframework.org/schema/aop"
securityAspect(SecurityAspect)
aop {
config("proxy-target-class":true) {
aspect(id:'theSecurityAspectDef', ref:'securityAspect') {
around method: "invoke", pointcut:"execution(* com.redpointtech.flex..*Service..*(..))"
}
}
}
}


I think this concludes my saga to get Flex services intercepted. I hope this helps you out.

6 comments:

Unknown said...

When I start my application, I get the following exception. Does that ring a bell to you?

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'adminService': Invocation of init method failed; nested exception is org.springframework.aop.framework.AopConfigException: Could not generate CGLIB subclass of class [class $Proxy14]: Common causes of this problem include using a final class or a non-visible class; nested exception is java.lang.IllegalArgumentException: Cannot subclass final class class $Proxy14
at org.grails.tomcat.TomcatServer.start(TomcatServer.groovy:135)
at grails.web.container.EmbeddableServer$start.call(Unknown Source)
at _GrailsRun_groovy$_run_closure5_closure12.doCall(_GrailsRun_groovy:158)
at _GrailsRun_groovy$_run_closure5_closure12.doCall(_GrailsRun_groovy)
at _GrailsSettings_groovy$_run_closure10.doCall(_GrailsSettings_groovy:282)
at _GrailsSettings_groovy$_run_closure10.call(_GrailsSettings_groovy)
at _GrailsRun_groovy$_run_closure5.doCall(_GrailsRun_groovy:149)
at _GrailsRun_groovy$_run_closure5.call(_GrailsRun_groovy)
at _GrailsRun_groovy.runInline(_GrailsRun_groovy:115)
at _GrailsRun_groovy.this$4$runInline(_GrailsRun_groovy)
at _GrailsRun_groovy$_run_closure1.doCall(_GrailsRun_groovy:59)
at RunApp$_run_closure1.doCall(RunApp.groovy:33)
at gant.Gant$_dispatch_closure4.doCall(Gant.groovy:324)
at gant.Gant$_dispatch_closure6.doCall(Gant.groovy:334)
at gant.Gant$_dispatch_closure6.doCall(Gant.groovy)
at gant.Gant.withBuildListeners(Gant.groovy:344)
at gant.Gant.this$2$withBuildListeners(Gant.groovy)
at gant.Gant$this$2$withBuildListeners.callCurrent(Unknown Source)
at gant.Gant.dispatch(Gant.groovy:334)
at gant.Gant.this$2$dispatch(Gant.groovy)
at gant.Gant.invokeMethod(Gant.groovy)
at gant.Gant.processTargets(Gant.groovy:495)
at gant.Gant.processTargets(Gant.groovy:480)
Caused by: org.springframework.aop.framework.AopConfigException: Could not generate CGLIB subclass of class [class $Proxy14]: Common causes of this problem include using a final class or a non-visible class; nested exception is java.lang.IllegalArgumentException: Cannot subclass final class class $Proxy14
... 23 more
Caused by: java.lang.IllegalArgumentException: Cannot subclass final class class $Proxy14
at net.sf.cglib.proxy.Enhancer.generateClass(Enhancer.java:446)
at net.sf.cglib.transform.TransformingClassGenerator.generateClass(TransformingClassGenerator.java:33)
at net.sf.cglib.core.DefaultGeneratorStrategy.generate(DefaultGeneratorStrategy.java:25)
at net.sf.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:216)
at net.sf.cglib.proxy.Enhancer.createHelper(Enhancer.java:377)
at net.sf.cglib.proxy.Enhancer.create(Enhancer.java:285)
... 23 more

Patrick Ryan said...

It looks to me like your adminService already has a proxy created, and the CGLIB library is trying to create a proxy of the proxy. Are you wrapping your service in other proxies and do they also use the proxy-target-class set to true?

Unknown said...

I'm not configuring any other AOP myself. So the only possibility I see is that a plugin does it. And the only plugins that I have installed and could proxy my service class are BlazeDS and Remoting. How are you configuring your BlazeDS destinations? Because if you are doing it like me, then it comes from the remoting plugin.

Unknown said...

I think I found the problem. I'm using Spring Security plugin to secure some of my controllers. So I've got acegi-0.5.2 installed and the problem only appears when I add this plugin. As for identifying where in this plugin there is a problem, it seems to be related to this Spring bean: daacc(org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator).

Can you confirm that you have the same problem when you install acegi plugin? Any idea how to modify it so that your AOP configuration works?

Unknown said...

FYI, I correctly isolated the problem in acegi-0.5.2. The problem comes from bug GRAILSPLUGINS-2049, solved in acegi-0.6 (to be released). So if you are using grails-acegi-0.5.2, the solution is to edit GrailsAcegiPlugin.groovy and remove daacc declaration

Patrick Ryan said...

Thank you for following up on your posts. I was going to start to look at this tonight. This is an interesting one that I bet took some digging.

Again - thanks for following up. I am sure this will help someone else.