I am attempting to upgrade to Groovy 1.1 beta into an application that has been using Spring and Groovy 1.0. (I want to be able to use annotations and generics.)
When attempting to use a Groovy bean that bas been instantiated via the lang:groovy method I'm getting the following error:
That stacktrace is from a test that I wrote to demonstrate the issue, but I get basically the same thing in my full application.Code:[java] java.lang.IllegalArgumentException: object is not an instance of declaring class [java] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) [java] at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) [java] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) [java] at java.lang.reflect.Method.invoke(Method.java:585) [java] at org.codehaus.groovy.runtime.metaclass.ReflectionMetaMethod.invoke(ReflectionMetaMethod.java:52) [java] at org.codehaus.groovy.runtime.MetaClassHelper.doMethodInvoke(MetaClassHelper.java:714) [java] at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:583) [java] at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:476) [java] at org.codehaus.groovy.runtime.Invoker.invokePogoMethod(Invoker.java:115) [java] at org.codehaus.groovy.runtime.Invoker.invokeMethod(Invoker.java:81) [java] at org.codehaus.groovy.runtime.InvokerHelper.invokeMethod(InvokerHelper.java:85) [java] at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.invokeMethodN(ScriptBytecodeAdapter.java:158) [java] at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.invokeMethod0(ScriptBytecodeAdapter.java:182) [java] at ServiceBeanImpl2.doService(script1185134866212.groovy:13) [java] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) [java] at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) [java] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) [java] at java.lang.reflect.Method.invoke(Method.java:585) [java] at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:299) [java] at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:172) [java] at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:139) [java] at org.springframework.aop.support.DelegatingIntroductionInterceptor.doProceed(DelegatingIntroductionInterceptor.java:127) [java] at org.springframework.aop.support.DelegatingIntroductionInterceptor.invoke(DelegatingIntroductionInterceptor.java:115) [java] at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:161) [java] at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202) [java] at $Proxy0.doService(Unknown Source) [java] at ServiceConsumerImpl.useService(ServiceConsumerImpl.java:10) [java] at Test.main(Test.java:18)
The issue seems to be when one Groovy bean attempts to access a service on another groovy bean. (ie. Groovy service bean ---depends_on---> Groovy DAO; or Groovy Struts 2 Action ---depends_on----> Groovy Service bean)
I believe the root of the problem is that each Groovy bean instantiated by Spring has its own classloader.
I have a test application that demonstrates the issue, and also shows the same exact code working in Groovy 1.0. I apologize that the download is on the large side. If I knew how to do dependencies in Ant I'd have done it.
http://mark.mjm.net/~mark/springGroovyTest.tar.gz
To build and run the test simply run ant in the root of the application. In the src-java there is a class Test.java with a main that instantiates a ServiceConsumer, then wires that to a service bean, ServiceBeanImpl2, and calls useService().
The service beans are two Groovy beans, in src-groovy, that are chained by configuration in resources/applicationContext.xml, ServiceBeanImpl2 to ServiceBeanImpl. ServiceBeanImpl2 simply calls the doService() method of ServiceBeanImpl.
In the course of the test I output the class loaders of the Groovy service beans. They each have a different GroovyClassLoader. It is my understanding that this is my design in Spring, but it appears to me to be the root of the issue. If I wire all of my Groovy objects together with Class instances loaded with the same GroovyClassLoader it all works as expected.
Any help on this issue would be greatly appreciated. I've sort of reached the end of what I know about Spring and Groovy.


Reply With Quote