Blake Underwood
Blake Underwood

Reputation: 31

StackOverflowError in java_lang_Class$isArray.call() when using Groovy's JsonBuilder

My Grails application and its integration tests are throwing a StackOverflowError when I try to use Groovy's JsonBuilder class on my domain classes. My code looks like this:

String result = new JsonBuilder(new MyDomainClass()) 

Since I found articles about JsonBuilder looping on self-references, I stripped down the domain class to almost nothing:

package com.mycompany.myapp.myarea
class MyDomainClass { }

but the stack overflow still reproduces. Here's the kicker. If I move the declaration of MyDomainClass out of its normal location and into the file where the unit test lives (i.e., take it out of its package), JsonBuilder works.

Stack trace below. Any help here?

Thanks, BGU

 java.lang.StackOverflowError
at java.security.AccessController.doPrivileged(Native Method)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.createCallStaticSite(CallSiteArray.java:62)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.createCallSite(CallSiteArray.java:159)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:45)
at java_lang_Class$isArray.call(Unknown Source)
at groovy.json.JsonOutput.toJson(JsonOutput.groovy:135)
at groovy.json.JsonOutput$toJson.callStatic(Unknown Source)
at groovy.json.JsonOutput$_toJson_closure2.doCall(JsonOutput.groovy:158)
at sun.reflect.GeneratedMethodAccessor974.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
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:1082)
at groovy.lang.ExpandoMetaClass.invokeMethod(ExpandoMetaClass.java:1106)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:906)
at groovy.lang.Closure.call(Closure.java:412)
at org.codehaus.groovy.runtime.DefaultGroovyMethods.callClosureForMapEntry(DefaultGroovyMethods.java:3870)
at org.codehaus.groovy.runtime.DefaultGroovyMethods.collect(DefaultGroovyMethods.java:2426)
at org.codehaus.groovy.runtime.DefaultGroovyMethods.collect(DefaultGroovyMethods.java:2443)
at org.codehaus.groovy.runtime.dgm$61.invoke(Unknown Source)
at org.codehaus.groovy.runtime.callsite.PojoMetaMethodSite$PojoMetaMethodSiteNoUnwrapNoCoerce.invoke(PojoMetaMethodSite.java:271)
at org.codehaus.groovy.runtime.callsite.PojoMetaMethodSite.call(PojoMetaMethodSite.java:53)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:116)
at groovy.json.JsonOutput.toJson(JsonOutput.groovy:154)
at groovy.json.JsonOutput$toJson$0.callStatic(Unknown Source)
at groovy.json.JsonOutput.toJson(JsonOutput.groovy:146)
at groovy.json.JsonOutput$toJson.callStatic(Unknown Source)
at groovy.json.JsonOutput$_toJson_closure1.doCall(JsonOutput.groovy:138)
at sun.reflect.GeneratedMethodAccessor978.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
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:1082)
at groovy.lang.ExpandoMetaClass.invokeMethod(ExpandoMetaClass.java:1106)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:906)
at groovy.lang.Closure.call(Closure.java:412)
at groovy.lang.Closure.call(Closure.java:425)
at org.codehaus.groovy.runtime.DefaultGroovyMethods.collect(DefaultGroovyMethods.java:2157)
at org.codehaus.groovy.runtime.DefaultGroovyMethods.collect(DefaultGroovyMethods.java:2128)
at org.codehaus.groovy.runtime.dgm$59.invoke(Unknown Source)
at org.codehaus.groovy.runtime.callsite.PojoMetaMethodSite$PojoMetaMethodSiteNoUnwrapNoCoerce.invoke(PojoMetaMethodSite.java:271)
at org.codehaus.groovy.runtime.callsite.PojoMetaMethodSite.call(PojoMetaMethodSite.java:53)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:116)
at groovy.json.JsonOutput.toJson(JsonOutput.groovy:138)
at groovy.json.JsonOutput$toJson.callStatic(Unknown Source)
at groovy.json.JsonOutput$_toJson_closure2.doCall(JsonOutput.groovy:158)
at sun.reflect.GeneratedMethodAccessor974.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
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:1082)
at groovy.lang.ExpandoMetaClass.invokeMethod(ExpandoMetaClass.java:1106)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:906)
at groovy.lang.Closure.call(Closure.java:412)
at org.codehaus.groovy.runtime.DefaultGroovyMethods.callClosureForMapEntry(DefaultGroovyMethods.java:3870)
at org.codehaus.groovy.runtime.DefaultGroovyMethods.collect(DefaultGroovyMethods.java:2426)
at org.codehaus.groovy.runtime.DefaultGroovyMethods.collect(DefaultGroovyMethods.java:2443)
at org.codehaus.groovy.runtime.dgm$61.invoke(Unknown Source)
at org.codehaus.groovy.runtime.callsite.PojoMetaMethodSite$PojoMetaMethodSiteNoUnwrapNoCoerce.invoke(PojoMetaMethodSite.java:271)
at org.codehaus.groovy.runtime.callsite.PojoMetaMethodSite.call(PojoMetaMethodSite.java:53)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:116)
at groovy.json.JsonOutput.toJson(JsonOutput.groovy:154)
at groovy.json.JsonOutput$toJson$0.callStatic(Unknown Source)
at groovy.json.JsonOutput.toJson(JsonOutput.groovy:146)
at groovy.json.JsonOutput$toJson.callStatic(Unknown Source)
at groovy.json.JsonOutput$_toJson_closure1.doCall(JsonOutput.groovy:138)
at sun.reflect.GeneratedMethodAccessor978.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
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:1082)
at groovy.lang.ExpandoMetaClass.invokeMethod(ExpandoMetaClass.java:1106)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:906)
at groovy.lang.Closure.call(Closure.java:412)
at groovy.lang.Closure.call(Closure.java:425)
at org.codehaus.groovy.runtime.DefaultGroovyMethods.collect(DefaultGroovyMethods.java:2157)
at org.codehaus.groovy.runtime.DefaultGroovyMethods.collect(DefaultGroovyMethods.java:2128)
at org.codehaus.groovy.runtime.dgm$59.invoke(Unknown Source)
at org.codehaus.groovy.runtime.callsite.PojoMetaMethodSite$PojoMetaMethodSiteNoUnwrapNoCoerce.invoke(PojoMetaMethodSite.java:271)
at org.codehaus.groovy.runtime.callsite.PojoMetaMethodSite.call(PojoMetaMethodSite.java:53)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:116)
at groovy.json.JsonOutput.toJson(JsonOutput.groovy:138)
at groovy.json.JsonOutput$toJson.callStatic(Unknown Source)
at groovy.json.JsonOutput$_toJson_closure2.doCall(JsonOutput.groovy:158)
at sun.reflect.GeneratedMethodAccessor974.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
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:1082)
at groovy.lang.ExpandoMetaClass.invokeMethod(ExpandoMetaClass.java:1106)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:906)
at groovy.lang.Closure.call(Closure.java:412)
at org.codehaus.groovy.runtime.DefaultGroovyMethods.callClosureForMapEntry(DefaultGroovyMethods.java:3870)
at org.codehaus.groovy.runtime.DefaultGroovyMethods.collect(DefaultGroovyMethods.java:2426)
at org.codehaus.groovy.runtime.DefaultGroovyMethods.collect(DefaultGroovyMethods.java:2443)
at org.codehaus.groovy.runtime.dgm$61.invoke(Unknown Source)
at org.codehaus.groovy.runtime.callsite.PojoMetaMethodSite$PojoMetaMethodSiteNoUnwrapNoCoerce.invoke(PojoMetaMethodSite.java:271)
at org.codehaus.groovy.runtime.callsite.PojoMetaMethodSite.call(PojoMetaMethodSite.java:53)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:116)
at groovy.json.JsonOutput.toJson(JsonOutput.groovy:154)
at groovy.json.JsonOutput$toJson$0.callStatic(Unknown Source)
at groovy.json.JsonOutput.toJson(JsonOutput.groovy:146)
at groovy.json.JsonOutput$toJson.callStatic(Unknown Source)
at groovy.json.JsonOutput$_toJson_closure1.doCall(JsonOutput.groovy:138)
at sun.reflect.GeneratedMethodAccessor978.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
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:1082)
at groovy.lang.ExpandoMetaClass.invokeMethod(ExpandoMetaClass.java:1106)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:906)
at groovy.lang.Closure.call(Closure.java:412)
at groovy.lang.Closure.call(Closure.java:425)
at org.codehaus.groovy.runtime.DefaultGroovyMethods.collect(DefaultGroovyMethods.java:2157)
at org.codehaus.groovy.runtime.DefaultGroovyMethods.collect(DefaultGroovyMethods.java:2128)
at org.codehaus.groovy.runtime.dgm$59.invoke(Unknown Source)
at org.codehaus.groovy.runtime.callsite.PojoMetaMethodSite$PojoMetaMethodSiteNoUnwrapNoCoerce.invoke(PojoMetaMethodSite.java:271)
at org.codehaus.groovy.runtime.callsite.PojoMetaMethodSite.call(PojoMetaMethodSite.java:53)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:116)
at groovy.json.JsonOutput.toJson(JsonOutput.groovy:138)
at groovy.json.JsonOutput$toJson.callStatic(Unknown Source)
at groovy.json.JsonOutput$_toJson_closure2.doCall(JsonOutput.groovy:158)
at sun.reflect.GeneratedMethodAccessor974.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
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:1082)
at groovy.lang.ExpandoMetaClass.invokeMethod(ExpandoMetaClass.java:1106)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:906)
at groovy.lang.Closure.call(Closure.java:412)
at org.codehaus.groovy.runtime.DefaultGroovyMethods.callClosureForMapEntry(DefaultGroovyMethods.java:3870)
at org.codehaus.groovy.runtime.DefaultGroovyMethods.collect(DefaultGroovyMethods.java:2426)
at org.codehaus.groovy.runtime.DefaultGroovyMethods.collect(DefaultGroovyMethods.java:2443)
at org.codehaus.groovy.runtime.dgm$61.invoke(Unknown Source)
at org.codehaus.groovy.runtime.callsite.PojoMetaMethodSite$PojoMetaMethodSiteNoUnwrapNoCoerce.invoke(PojoMetaMethodSite.java:271)...

Upvotes: 3

Views: 577

Answers (1)

Martin Hauner
Martin Hauner

Reputation: 1733

I stepped into the code a little bit, and JsonBuilder has a number of type checks to decide how the object should be written. In case of the domain class it matches Iterable. It then tries to loop over it and write each item etc.

Strange thing is that next after casting the object to Iterable returns the objects itself.... causing and endless loop.

It works if I write the following (still fails without the explicit cast):

String result = new JsonBuilder((Map)(new MyDomainClass().properties))

Upvotes: 1

Related Questions