There is always some surprises when using Groovy in Java programs. For example, you can wire any 2 Groovy beans in Spring even though these 2 Groovy beans do not implement any Java interface. For example, GroovyBean1 is defined as follow:
package test ;
public class GroovyBean1 {
def groovyBean2 ;
}
And GroovyBean2 is defined as follow:
package test ;
public class GroovyBean2 {
}
In the spring xml config file, you can wire them as:
...
<lang:groovy id="groovyBean1" source="classpath:test/GroovyBean1.groovy">
<lang:property name="groovyBean2" ref="groovyBean2"/>
</lang:groovy>
<lang:groovy id="groovyBean2" source="classpath:test/GroovyBean2.groovy"/>
...
If you load the above spring xml config file with ClassPathXmlApplicationContext, you will find that "GroovyBean2" is successfully injected into "GroovyBean1". But if you change GroovyBean1 source code as follow:
package test ;
public class GroovyBean1 {
GroovyBean2 groovyBean2 ; // <-- change untype variable to "GROOVY" type variable
}
ClassPathXmlApplicationContext will throw an Exception when it tries to inject "GroovyBean2" into "GroovyBean1". Why does Spring IOC not work with "pure" groovy objects that does not implements any Java interface? The problem is due to Groovy class loader. The "GroovyBean2" definition in GroovyBean1 and the "GroovyBean2" definition in Spring xml file belong to different class loader so the Spring IOC throws Exception. Is it possible to solve this problem by using a single GroovyClassLoader to load both GroovyBean1 and GroovyBean2 objects. The answer is simply "NO"!!! Because GroovyClassLoader always create a new InnerLoader when compile a groovy script file. If anyone has a solution, please leave a comment.
chris tam
Hong Kong
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment