WendyG
WendyG

Reputation: 587

groovy JSONBuilder on object throw StackOverflowException

Edit to add it is the LocalDate. I found this issue https://issues.apache.org/jira/browse/GROOVY-7682 but this is from 2016 and still open

If I swap the LocalDate for Date it works. Can anyone help with this?

I have this object I am trying to convert to JSON so I am using JsonBuilder and it is throwing StackOverflow exception.

I have got it down to this short snippet of code by writing a test.

This is the line

Object anyObject = new TestRetentionUpdate ()

new JsonBuilder( anyObject ).toPrettyString(  )

and the class in question

class TestRetentionUpdate {

  public static final String FRANK = 'FRANK'
  static final String ISO_8601_DATE_ONLY = 'yyyy-MM-dd'
  String urfNumber = 'gbfrvs'
  String channel = FRANK
  String requestFlag = '1'
  String uniqueIdentifier = 'gwirew'
  String partnerName = FRANK
  String policyNumber = 'IA12467854'
  String retentionStatus = 'Succesful'
  String cancellationReason = 'why'

  LocalDate policyStartDate = LocalDate.now()

  LocalDate policyEndDate = LocalDate.now()

  LocalDate cancellationDate = null

  String cancellationType ='Waht'
  String premiumAmount = '100'
  String refundAmount = '10'
  String refundGrid = '10%'
}

This is the stack trace, sorry it is so long but it is an overflow error:

0 = {StackTraceElement@2861} "java.security.AccessController.doPrivileged(Native Method)"
1 = {StackTraceElement@2862} "java.net.URLClassLoader.findClass(URLClassLoader.java:362)"
2 = {StackTraceElement@2863} "java.lang.ClassLoader.loadClass(ClassLoader.java:418)"
3 = {StackTraceElement@2864} "java.lang.ClassLoader.loadClass(ClassLoader.java:405)"
4 = {StackTraceElement@2865} "sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:352)"
5 = {StackTraceElement@2866} "java.lang.ClassLoader.loadClass(ClassLoader.java:351)"
6 = {StackTraceElement@2867} "java.lang.Class.forName0(Native Method)"
7 = {StackTraceElement@2868} "java.lang.Class.forName(Class.java:264)"
8 = {StackTraceElement@2869} "groovy.lang.MetaClassRegistry$MetaClassCreationHandle.createWithCustomLookup(MetaClassRegistry.java:144)"
9 = {StackTraceElement@2870} "groovy.lang.MetaClassRegistry$MetaClassCreationHandle.create(MetaClassRegistry.java:139)"
10 = {StackTraceElement@2871} "org.codehaus.groovy.reflection.ClassInfo.getMetaClassUnderLock(ClassInfo.java:286)"
11 = {StackTraceElement@2872} "org.codehaus.groovy.reflection.ClassInfo.getMetaClass(ClassInfo.java:329)"
12 = {StackTraceElement@2873} "org.codehaus.groovy.reflection.ClassInfo.getMetaClass(ClassInfo.java:339)"
13 = {StackTraceElement@2874} "org.codehaus.groovy.runtime.metaclass.MetaClassRegistryImpl.getMetaClass(MetaClassRegistryImpl.java:276)"
14 = {StackTraceElement@2875} "org.codehaus.groovy.runtime.InvokerHelper.getMetaClass(InvokerHelper.java:965)"
15 = {StackTraceElement@2876} "org.codehaus.groovy.runtime.DefaultGroovyMethods.getMetaPropertyValues(DefaultGroovyMethods.java:534)"
16 = {StackTraceElement@2877} "org.codehaus.groovy.runtime.DefaultGroovyMethods.getProperties(DefaultGroovyMethods.java:553)"
17 = {StackTraceElement@2878} "groovy.json.DefaultJsonGenerator.getObjectProperties(DefaultJsonGenerator.java:242)"
18 = {StackTraceElement@2879} "groovy.json.DefaultJsonGenerator.writeObject(DefaultJsonGenerator.java:236)"
19 = {StackTraceElement@2880} "groovy.json.DefaultJsonGenerator.writeObject(DefaultJsonGenerator.java:164)"
20 = {StackTraceElement@2881} "groovy.json.DefaultJsonGenerator.writeIterator(DefaultJsonGenerator.java:402)"
21 = {StackTraceElement@2882} "groovy.json.DefaultJsonGenerator.writeObject(DefaultJsonGenerator.java:202)"
22 = {StackTraceElement@2883} "groovy.json.DefaultJsonGenerator.writeMapEntry(DefaultJsonGenerator.java:387)"
23 = {StackTraceElement@2884} "groovy.json.DefaultJsonGenerator.writeMap(DefaultJsonGenerator.java:375)"
24 = {StackTraceElement@2885} "groovy.json.DefaultJsonGenerator.writeObject(DefaultJsonGenerator.java:237)"
25 = {StackTraceElement@2886} "groovy.json.DefaultJsonGenerator.writeObject(DefaultJsonGenerator.java:164)"
26 = {StackTraceElement@2887} "groovy.json.DefaultJsonGenerator.writeIterator(DefaultJsonGenerator.java:402)"
27 = {StackTraceElement@2888} "groovy.json.DefaultJsonGenerator.writeObject(DefaultJsonGenerator.java:202)"
28 = {StackTraceElement@2889} "groovy.json.DefaultJsonGenerator.writeMapEntry(DefaultJsonGenerator.java:387)"
29 = {StackTraceElement@2890} "groovy.json.DefaultJsonGenerator.writeMap(DefaultJsonGenerator.java:375)"
30 = {StackTraceElement@2891} "groovy.json.DefaultJsonGenerator.writeObject(DefaultJsonGenerator.java:237)"
31 = {StackTraceElement@2892} "groovy.json.DefaultJsonGenerator.writeObject(DefaultJsonGenerator.java:164)"
32 = {StackTraceElement@2893} "groovy.json.DefaultJsonGenerator.writeIterator(DefaultJsonGenerator.java:402)"
33 = {StackTraceElement@2894} "groovy.json.DefaultJsonGenerator.writeObject(DefaultJsonGenerator.java:202)"
34 = {StackTraceElement@2895} "groovy.json.DefaultJsonGenerator.writeMapEntry(DefaultJsonGenerator.java:387)"
35 = {StackTraceElement@2896} "groovy.json.DefaultJsonGenerator.writeMap(DefaultJsonGenerator.java:375)"
36 = {StackTraceElement@2897} "groovy.json.DefaultJsonGenerator.writeObject(DefaultJsonGenerator.java:237)"

etc

Upvotes: 1

Views: 1899

Answers (3)

Alex
Alex

Reputation: 201

You can customize json serialization. At the beginnig create your own jsonOutput and use it for JsonBuilder:

def jsonOutput = JsonGenerator.Options()
        .excludeNulls()
        .dateFormat('dd-MM-yyyy')
        .build()
def jsonBuilder = new JsonBuilder(jsonOutput)

Upvotes: 2

Yuri G
Yuri G

Reputation: 1213

JsonBuilder doesn't "know" what to do with LocalDate.

If you remove this, the rest of the object serializes like a charm.

So it goes with good 'ol regular Date.

What could be the remedy for this if you , besides building JSON "manually" (like, with closures, as you can find in the example coming with docs) and/or having these fields already serialized to String or regular Date in your object?

I, honestly, don't have an idea regarding that, as I'm not aware what's the underlying implementation of either JsonBuilder & LocalDate.

What I can assess, though, is that the problem lays there.

Upvotes: 1

WendyG
WendyG

Reputation: 587

So the problem was LocalDate

I found this issue https://issues.apache.org/jira/browse/GROOVY-7682 but this is from 2016 and still open

If I swap the LocalDate for Date it works.

I found this somewhere else

Date.from(LocalDate.now().atStartOfDay().atZone(ZoneId.systemDefault()).toInstant())

as Date.from takes an Instant.

But actually for my use I will just make it a string

Upvotes: 0

Related Questions