|
View:
New views
10 Messages
—
Rating Filter:
Alert me
|
|
|
Grails and Spring AOPHi,
I am desperately trying to make Spring AOP work in my Grails project. I define an advice on a service method, which works fine, but as soon as the pointcut matches and the advice is executed, Grails throws an exception: "java.lang.IllegalArgumentException: object is not an instance of declaring class" I guess this has something to do with Groovy and meta objects? Not sure. Since I have seen Graeme saying on this mailing list that Spring AOP works just fine in Grails, I am wondering what I am doing wrong. Thanks, Matthias PS: Here is my resources.xml, it's just for testing purposes right now (MyAspect is annotated with @Aspect and defines a public method "foo"): <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd"> <aop:config> <aop:aspect id="theAspect" ref="testAspect"> <aop:pointcut id="exec" expression="execution(* org.myapp.services.MyService.*(..))" /> <aop:before pointcut-ref="exec" method="foo" /> </aop:aspect> </aop:config> <bean id="testAspect" class="org.myapp.MyAspect"> </bean> </beans> --------------------------------------------------------------------- To unsubscribe from this list, please visit: http://xircles.codehaus.org/manage_email |
|
|
Re: Grails and Spring AOPI had this kind of problem (object is not an instance of declaring
class) when trying to use Java + Groovy. My solution was creating an interface and implementing it on the Service. Then, i used the interface where should be the service. On Tue, Sep 23, 2008 at 1:26 PM, Matthias <m.kaeppler@...> wrote: Hi, -- Fernando "Takai" http://flickr.com/photos/supeertakai http://fernandotakai.wordpress.com http://fernandotakai.jaiku.com |
|
|
Re: Grails and Spring AOPFernando Takai <fernando.takai <at> gmail.com> writes:
> > I had this kind of problem (object is not an instance of declaring > class) when trying to use Java + Groovy. My solution was creating an interface and implementing it on the Service. Then, i used the interface where should be the service. I see, and did you try the same thing for Grails Controllers, too? I tried to match a controller using a pointcut like this: execution(* org.myapp.controllers.*Controller$_closure*.doCall(..)) but it won't match. It won't even match when supplying a concrete Controller class and closure number, e.g. MyController$_closure1. any ideas? Thanks for your input. --------------------------------------------------------------------- To unsubscribe from this list, please visit: http://xircles.codehaus.org/manage_email |
|
|
Re: Grails and Spring AOPMatthias <m.kaeppler <at> gmail.com> writes:
> > Hi, > > I am desperately trying to make Spring AOP work in my Grails project. I define > an advice on a service method, which works fine, but as soon as the pointcut > matches and the advice is executed, Grails throws an exception: > > "java.lang.IllegalArgumentException: object is not an instance of declaring > class" > > [...] > Hi guys, I still haven't solved this puzzle. Surely anyone has more experience with this than I do? Any help appreciated! Best, Matthias --------------------------------------------------------------------- To unsubscribe from this list, please visit: http://xircles.codehaus.org/manage_email |
|
|
Re: Re: Grails and Spring AOPI had the same issue and resolved it by creating an
interface which my class then implemented.
Regards Rob Matthias <m.kaeppler <at> gmail.com> writes: |
|
|
Re: Re: Grails and Spring AOP> I still haven't solved this puzzle. Surely anyone has more experience with this
> than I do? Hi, I'm not sure anyone has tried with AOP 2. Internally, Grails uses the old AOP 1 style quite extensively, but I'm not sure the newer style works with Groovy classes, and in particular closures. With the Profiler Plugin for example, I used different interception techniques - basically a mix of AOP 1, meta-programming, and a special closure wrapper. That said, it's been quite a while since I last looked at Spring's AOP support and I can't remember how the AOP 2 style works at all, sorry. Peter -- Software Engineer G2One, Inc. http://www.g2one.com/ --------------------------------------------------------------------- To unsubscribe from this list, please visit: http://xircles.codehaus.org/manage_email |
|
|
Re: Grails and Spring AOPHi Robert,
Robert Hunter <robert.hunter <at> patersons.net> writes: > > > I had the same issue and resolved it by creating an > interface which my class then implemented. yes, that's what Fernando suggested earlier in this thread, but that does not work with Grails Controllers, because those are based on closures -- unless of course I would only use the closures as wrappers around the interface methods and apply any advice to the latter, e.g.: class MyController implements MyInterface { // the controller closure called from a Web client def foo = { // only redirect -- aspect would match this call I guess? fooFromInterface() } public void fooFromInterface() { // perform actual controller logic } } not sure if this works... btw, will some closure "foo" name-clash with a public method foo() from an interface? Best, Matthias --------------------------------------------------------------------- To unsubscribe from this list, please visit: http://xircles.codehaus.org/manage_email |
|
|
Re: Grails and Spring AOPGuys,
I have got it working, somehow, but it involves a workaround which I am not happy with. First, two things seem to be required in order for advice being applied to an object in Grails: 1) As has been said before, it must be of the same type that is referenced in the aspect declaration, otherwise an "instance is not of declaring type" error is thrown. This can be solved by implementing an interface and match the pointcut against that interface. 2) The object that is being advised must be a Spring bean, i.e. it must be managed by the container. This is not true for Grails Controllers, and this is the reason why I was able to apply advice to my services, but not to my controllers. Unfortunately, controllers are instantiated per-request and parameters bound as such. So what I did was for each controller create an interface and an implementation of that interface, to which the controller closures forward, e.g.: interface Foo { def foo(def controller) } // this must be a managed bean class FooImpl { def foo(def controller) { controller.flash.message = "advice applied!" } } class FooController { def impl // injected by spring def fooClosure = { // forward call impl.foo(this) } } Now any advice declared on Foo will match, however, this solution has many drawbacks: Firstly, of course, another level of indirection is introduced, with all the related drawbacks (performance, readability, ...) Secondly, all controller logic is now moved to FooImpl, but FooImpl needs access to "private" controller fields (e.g. params, flash, ...). Given, right now there is no such thing as private fields or methods in Groovy, but this may change with upcoming versions I guess and break this workaround (unless there will be public getters for everything). Lastly, every controller impl has to be declared manually as a bean. So, does anyone have a better solution at hand, because I am not very happy with this. Thanks and best regards, Matthias --------------------------------------------------------------------- To unsubscribe from this list, please visit: http://xircles.codehaus.org/manage_email |
|
|
Re: Re: Grails and Spring AOPI'm also having problems with AOP in Grails 1.1. 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 simple Hello World app that does almost nothing: my controller calls my service and both print log messages. The service implements an interface as described earlier in this thread (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, 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. This is my first time using Spring AOP, so I must be missing something simple. Any thoughts are very much appreciated. I uploaded my hello world app to google code for anyone interested: http://code.google.com/p/grails-aop-hello-world/ Also, the relevant bits of my app are included below in case someone has any ideas. Thanks, Scott 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" } } } ------------------------------ Again, any thoughts or pointers are appreciated. Thanks in advance. ------------------------------------------------- Scott Vlaminck // scott@... Refactr LLC // http://refactr.com mobile // 612-386-9382 ------------------------------------------------- On Mon, Oct 20, 2008 at 6:08 AM, Matthias <m.kaeppler@...> wrote: > Guys, > > I have got it working, somehow, but it involves a workaround which I am not > happy with. First, two things seem to be required in order for advice being > applied to an object in Grails: > > 1) As has been said before, it must be of the same type that is referenced in > the aspect declaration, otherwise an "instance is not of declaring type" error > is thrown. This can be solved by implementing an interface and match the > pointcut against that interface. > > 2) The object that is being advised must be a Spring bean, i.e. it must be > managed by the container. This is not true for Grails Controllers, and this > is the reason why I was able to apply advice to my services, but not to my > controllers. > > Unfortunately, controllers are instantiated per-request and parameters > bound as such. So what I did was for each controller create an interface > and an implementation of that interface, to which the controller closures > forward, e.g.: > > interface Foo { > def foo(def controller) > } > > // this must be a managed bean > class FooImpl { > def foo(def controller) { > controller.flash.message = "advice applied!" > } > } > > class FooController { > def impl // injected by spring > > def fooClosure = { > // forward call > impl.foo(this) > } > } > > Now any advice declared on Foo will match, however, this solution has many > drawbacks: Firstly, of course, another level of indirection is introduced, > with all the related drawbacks (performance, readability, ...) > Secondly, all controller logic is now moved to FooImpl, but FooImpl needs > access to "private" controller fields (e.g. params, flash, ...). > Given, right now there is no such thing as private fields or methods in > Groovy, but this may change with upcoming versions I guess and break > this workaround (unless there will be public getters for everything). > Lastly, every controller impl has to be declared manually as a bean. > > So, does anyone have a better solution at hand, because I am not very > happy with this. > > Thanks and best regards, > Matthias > > > --------------------------------------------------------------------- > To unsubscribe from this list, please visit: > > http://xircles.codehaus.org/manage_email > > > --------------------------------------------------------------------- To unsubscribe from this list, please visit: http://xircles.codehaus.org/manage_email |
|
|
Re: Re: Grails and Spring AOPFollowing up on my own post: I was able to get AOP before, after, and
around advice working. I've created an example app with tests and with a service that is wrapped with around advice. It's hosted here for anyone else having problems: http://code.google.com/p/grails-aop-hello-world/source/checkout I've also detailed my problems and solutions here: http://refactr.com/blog/2009/05/problems-with-aop-in-grails-1-1/ http://refactr.com/blog/2009/06/success-with-aop-in-grails-11/ Hopefully it will help someone in the future. Scott ------------------------------------------------- Scott Vlaminck // scott@... Refactr LLC // http://refactr.com mobile // 612-386-9382 ------------------------------------------------- On Mon, May 11, 2009 at 8:50 AM, Scott Vlaminck <scott@...> wrote: > I'm also having problems with AOP in Grails 1.1. 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 simple Hello World app that does > almost nothing: my controller calls my service and both print log > messages. The service implements an interface as described earlier in > this thread (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, 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. > > This is my first time using Spring AOP, so I must be missing something > simple. Any thoughts are very much appreciated. I uploaded my hello > world app to google code for anyone interested: > http://code.google.com/p/grails-aop-hello-world/ > > Also, the relevant bits of my app are included below in case someone > has any ideas. > > Thanks, > Scott > > > 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" > } > } > } > ------------------------------ > > > > > Again, any thoughts or pointers are appreciated. Thanks in advance. > > > > ------------------------------------------------- > Scott Vlaminck // scott@... > Refactr LLC // http://refactr.com > mobile // 612-386-9382 > ------------------------------------------------- > > > > On Mon, Oct 20, 2008 at 6:08 AM, Matthias <m.kaeppler@...> wrote: >> Guys, >> >> I have got it working, somehow, but it involves a workaround which I am not >> happy with. First, two things seem to be required in order for advice being >> applied to an object in Grails: >> >> 1) As has been said before, it must be of the same type that is referenced in >> the aspect declaration, otherwise an "instance is not of declaring type" error >> is thrown. This can be solved by implementing an interface and match the >> pointcut against that interface. >> >> 2) The object that is being advised must be a Spring bean, i.e. it must be >> managed by the container. This is not true for Grails Controllers, and this >> is the reason why I was able to apply advice to my services, but not to my >> controllers. >> >> Unfortunately, controllers are instantiated per-request and parameters >> bound as such. So what I did was for each controller create an interface >> and an implementation of that interface, to which the controller closures >> forward, e.g.: >> >> interface Foo { >> def foo(def controller) >> } >> >> // this must be a managed bean >> class FooImpl { >> def foo(def controller) { >> controller.flash.message = "advice applied!" >> } >> } >> >> class FooController { >> def impl // injected by spring >> >> def fooClosure = { >> // forward call >> impl.foo(this) >> } >> } >> >> Now any advice declared on Foo will match, however, this solution has many >> drawbacks: Firstly, of course, another level of indirection is introduced, >> with all the related drawbacks (performance, readability, ...) >> Secondly, all controller logic is now moved to FooImpl, but FooImpl needs >> access to "private" controller fields (e.g. params, flash, ...). >> Given, right now there is no such thing as private fields or methods in >> Groovy, but this may change with upcoming versions I guess and break >> this workaround (unless there will be public getters for everything). >> Lastly, every controller impl has to be declared manually as a bean. >> >> So, does anyone have a better solution at hand, because I am not very >> happy with this. >> >> Thanks and best regards, >> Matthias >> >> >> --------------------------------------------------------------------- >> To unsubscribe from this list, please visit: >> >> http://xircles.codehaus.org/manage_email >> >> >> > --------------------------------------------------------------------- To unsubscribe from this list, please visit: http://xircles.codehaus.org/manage_email |
| Free embeddable forum powered by Nabble | Forum Help |