Skip to content

Commit 5d6be9b

Browse files
authored
Skipping over groovy metadata class + groovy test. (#118)
1 parent e352cac commit 5d6be9b

File tree

6 files changed

+127
-11
lines changed

6 files changed

+127
-11
lines changed

jr-objects/pom.xml

+21
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,12 @@ has no other dependencies, and provides additional builder-style content generat
4040
<artifactId>jackson-core</artifactId>
4141
<version>${jackson.version.core}</version>
4242
</dependency>
43+
<dependency>
44+
<groupId>org.apache.groovy</groupId>
45+
<artifactId>groovy</artifactId>
46+
<version>4.0.18</version>
47+
<scope>test</scope>
48+
</dependency>
4349
</dependencies>
4450

4551
<build>
@@ -54,6 +60,21 @@ has no other dependencies, and provides additional builder-style content generat
5460
</configuration>
5561

5662
</plugin>
63+
64+
<!-- 20-Feb-2024, tatu: Need Groovy compilation for one test
65+
-->
66+
<plugin>
67+
<groupId>org.codehaus.gmaven</groupId>
68+
<artifactId>gmaven-plugin</artifactId>
69+
<version>1.5</version>
70+
<executions>
71+
<execution>
72+
<goals>
73+
<goal>testCompile</goal>
74+
</goals>
75+
</execution>
76+
</executions>
77+
</plugin>
5778
<plugin>
5879
<groupId>com.google.code.maven-replacer-plugin</groupId>
5980
<artifactId>replacer</artifactId>

jr-objects/src/main/java/com/fasterxml/jackson/jr/ob/impl/BeanPropertyIntrospector.java

+11-8
Original file line numberDiff line numberDiff line change
@@ -116,8 +116,7 @@ private static void _introspect(Class<?> currType, Map<String, PropBuilder> prop
116116
final int flags = m.getModifiers();
117117
// 13-Jun-2015, tatu: Skip synthetic, bridge methods altogether, for now
118118
// at least (add more complex handling only if absolutely necessary)
119-
if (Modifier.isStatic(flags)
120-
|| m.isSynthetic() || m.isBridge()) {
119+
if (Modifier.isStatic(flags) || m.isSynthetic() || m.isBridge() || isGroovyMetaClass(m.getReturnType())) {
121120
continue;
122121
}
123122
Class<?> argTypes[] = m.getParameterTypes();
@@ -158,12 +157,7 @@ private static void _introspect(Class<?> currType, Map<String, PropBuilder> prop
158157
}
159158

160159
private static PropBuilder _propFrom(Map<String,PropBuilder> props, String name) {
161-
PropBuilder prop = props.get(name);
162-
if (prop == null) {
163-
prop = Prop.builder(name);
164-
props.put(name, prop);
165-
}
166-
return prop;
160+
return props.computeIfAbsent(name, Prop::builder);
167161
}
168162

169163
private static String decap(String name) {
@@ -182,4 +176,13 @@ private static String decap(String name) {
182176
return name;
183177
}
184178

179+
/**
180+
* Helper method to detect Groovy's problematic metadata accessor type.
181+
*
182+
* @implNote Groovy MetaClass have cyclic reference, and hence the class containing it should not be serialised without
183+
* either removing that reference, or skipping over such references.
184+
*/
185+
protected static boolean isGroovyMetaClass(Class<?> clazz) {
186+
return "groovy.lang.MetaClass".equals(clazz.getName());
187+
}
185188
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
package com.fasterxml.jackson.jr
2+
3+
import org.junit.Test
4+
import org.junit.Assert
5+
6+
import com.fasterxml.jackson.jr.ob.JSON
7+
import com.fasterxml.jackson.jr.ob.TestBase
8+
9+
class GroovyTest
10+
{
11+
@Test
12+
void testSimpleGroovyObject() throws Exception {
13+
def json = JSON.std.asString(new GroovyOb())
14+
def expected = """{"AAAAA_A_Field_Starting_With_Two_Capital_Letters":"XYZ","aDouble":0.0,"aPublicInitializedInteger":56,"aPublicInitializedIntegerObject":1516,"aPublicUninitializedInteger":0,"anInitializedIntegerObject":1112,"anInitializedPublicString":"stringData","anInitializedString":"ABC","anInteger":0,"anIntegerWithValue":12}"""
15+
Assert.assertEquals(json, expected)
16+
}
17+
}
18+
19+
class GroovyOb {
20+
int anInteger
21+
int anIntegerWithValue = 12
22+
23+
static int anStaticInteger = 34
24+
static int anStaticIntegerWithValue = 34
25+
26+
public int aPublicUninitializedInteger
27+
public int aPublicInitializedInteger = 56
28+
29+
private int aPrivateUninitializedInteger
30+
private int aPrivateInitializedInteger = 78
31+
32+
public static int aPublicStaticUninitializedInteger
33+
public static int aPublicStaticInitializedInteger = 910
34+
35+
Integer anIntegerObject
36+
Integer anInitializedIntegerObject = 1112
37+
38+
static Integer aStaticIntegerObject
39+
static Integer aStaticInitializedIntegerObject = 1314
40+
41+
public Integer aPublicUninitializedIntegerObject
42+
public Integer aPublicInitializedIntegerObject = 1516
43+
44+
public static Integer aPublicStaticUninitializedIntegerObject
45+
public static Integer aPublicStaticInitializedIntegerObject = 1718
46+
47+
String aString
48+
String anInitializedString = "ABC"
49+
50+
static String aStaticString = "jacksonJR"
51+
52+
public String aPublicString
53+
public String anInitializedPublicString = "stringData"
54+
55+
public String AAAAA_A_Field_Starting_With_Two_Capital_Letters = "XYZ"
56+
//Other Items
57+
public static String staticStr = "jacksonJR" // Public Static Object
58+
static int anStaticInt // Uninitialized Static Object
59+
public double aDouble // uninitialized primitive
60+
public Double aDoubleObject // testing boxing object
61+
private int hiddenvalue = 123 // private value
62+
}

jr-stree/src/main/java/com/fasterxml/jackson/jr/stree/util/JrsTreeTraversingParser.java

+20-2
Original file line numberDiff line numberDiff line change
@@ -193,10 +193,16 @@ public boolean isClosed() {
193193
*/
194194

195195
@Override
196-
public String getCurrentName() {
196+
public String currentName() {
197197
return (_nodeCursor == null) ? null : _nodeCursor.getCurrentName();
198198
}
199199

200+
@Override
201+
@Deprecated // since 2.17
202+
public String getCurrentName() {
203+
return currentName();
204+
}
205+
200206
@Override
201207
public void overrideCurrentName(String name)
202208
{
@@ -211,13 +217,25 @@ public JsonStreamContext getParsingContext() {
211217
}
212218

213219
@Override
220+
public JsonLocation currentTokenLocation() {
221+
return JsonLocation.NA;
222+
}
223+
224+
@Override
225+
@Deprecated // since 2.17
214226
public JsonLocation getTokenLocation() {
227+
return currentTokenLocation();
228+
}
229+
230+
@Override
231+
public JsonLocation currentLocation() {
215232
return JsonLocation.NA;
216233
}
217234

218235
@Override
236+
@Deprecated // since 2.17
219237
public JsonLocation getCurrentLocation() {
220-
return JsonLocation.NA;
238+
return currentLocation();
221239
}
222240

223241
/*

release-notes/CREDITS-2.x

+10-1
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,12 @@ Jonas Konrad (@yawkat)
2323
* Suggested #88: Make `jr-stree` dependency to `jr-objects` optional
2424
(2.13.0)
2525

26+
Nikolay Chashnikov (@chashnikov)
27+
28+
* Requested #93: Skip serialization of `groovy.lang.MetaClass`
29+
values to avoid `StackOverflowError`
30+
(2.17.0)
31+
2632
Gerben Oolbekkink (@github)
2733

2834
* Reported #98: `module-info.java` of `jr-stree` refers to module `com.fasterxml.jackson.jr.ob.api`,
@@ -42,5 +48,8 @@ Julian Honnen (@jhonnen)
4248

4349
@Shounaks
4450

45-
* Contributed implf ro #100: Add support for `java.time` (Java 8 date/time) types
51+
* Contributed fix for #93: Skip serialization of `groovy.lang.MetaClass` values
52+
to avoid `StackOverflowError`
53+
(2.17.0)
54+
* Contributed impl for #100: Add support for `java.time` (Java 8 date/time) types
4655
(2.17.0)

release-notes/VERSION-2.x

+3
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@ Modules:
1515

1616
#78: Deserializes "null" to "0.0" for `java.lang.Double` (wrapper)
1717
(reported by @bill-phast)
18+
#93: Skip serialization of `groovy.lang.MetaClass` values to avoid `StackOverflowError`
19+
(requested by Nikolay C)
20+
(fix contributed by @Shounaks)
1821
#100: Add support for `java.time` (Java 8 date/time) types
1922
(requested by @sebastian-zero)
2023
(contributed by @Shounaks)

0 commit comments

Comments
 (0)