Details
-
Type:
Bug
-
Status:
Open
-
Priority:
Major
-
Resolution: Unresolved
-
Affects Version/s: 1.7.10, 2.0-beta-2, 1.8.6
-
Fix Version/s: None
-
Component/s: groovy-jdk
-
Labels:None
-
Environment:Windows 7, IntelliJ IDEA
-
Number of attachments :
Description
You get a StackOverflow Exception when running following code:
A.groovy
abstract class A { A attach(){ System.out.println( "A does something else"); return this; } }
B.groovy
class B extends A { @Override B attach(){ System.out.println("B does something else"); return (B) super.attach(); } }
C.groovy
class C extends B { @Override C attach(){ System.out.println("C does something else"); return (C) super.attach(); } }
Test.groovy
C c = new C(); c.attach();
This bug only occurs when the depth of the class hierarchy exceeds two classes.
Moreover this bug seems depend on the method name! If you try attachMe() as method name the Stackoverflow Exception won't be raised.
The whole ErrorOutput can be found attached.
Error.output
C does something else C does something else C does something else C does something else Exception in thread "main" java.lang.StackOverflowError at groovy.lang.MetaClassImpl.getMetaProperty(MetaClassImpl.java:2441) at groovy.lang.MetaClassImpl.getMetaProperty(MetaClassImpl.java:2415) at groovy.lang.MetaClassImpl.getProperty(MetaClassImpl.java:1510) at groovy.lang.MetaClassImpl.getProperty(MetaClassImpl.java:3308) at org.codehaus.groovy.runtime.callsite.ClassMetaClassGetPropertySite.getProperty(ClassMetaClassGetPropertySite.java:48) at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callGetProperty(AbstractCallSite.java:227) at C.attach(C.groovy:20) at C.attach(C.groovy) at B.attach(B.groovy) at C.super$3$attach(C.groovy) at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:90) at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:233) at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1047) at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.invokeMethodOnSuperN(ScriptBytecodeAdapter.java:128) at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.invokeMethodOnSuper0(ScriptBytecodeAdapter.java:148)
Had a quick look at this. Groovy is creating bridge methods for each covariant return type, e.g. for class C, the methods "A attach()", "B attach()" are added in addition to the one in the class itself, i.e. "C attach()". Depending on the order these are placed in the file, you will get strange behaviour. The workaround is to have A as your return type everywhere for the "attach" method.