Skip to content

Commit 9434f51

Browse files
committed
Fix #357 properly. Finally!
1 parent c799b42 commit 9434f51

File tree

5 files changed

+44
-55
lines changed

5 files changed

+44
-55
lines changed

release-notes/VERSION

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ Project: jackson-databind
1212
#291: @JsonTypeInfo with As.EXTERNAL_PROPERTY doesn't work if external type property
1313
is referenced more than once
1414
(reported by Starkom@github)
15+
#357: StackOverflowError with contentConverter that returns array type
16+
(reported by Florian S)
1517
#476: Allow "Serialize as POJO" using `@JsonFormat(shape=Shape.OBJECT)` class annotation
1618
#507: Support for default `@JsonView` for a class
1719
(suggested by Mark W)

src/main/java/com/fasterxml/jackson/databind/ser/std/StdDelegatingSerializer.java

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -160,15 +160,11 @@ public void serialize(Object value, JsonGenerator gen, SerializerProvider provid
160160
provider.defaultSerializeNull(gen);
161161
return;
162162
}
163-
System.err.println(" delegating.serialize. value: "+value.getClass());
164-
165163
// 02-Apr-2015, tatu: As per [databind#731] may need to do dynamic lookup
166164
JsonSerializer<Object> ser = _delegateSerializer;
167165
if (ser == null) {
168-
System.err.println("DEBUG: dynamic lookup for delegator... ");
169166
ser = _findSerializer(delegateValue, provider);
170167
}
171-
System.err.println(" delegating.serialize with -> "+ser);
172168
ser.serialize(delegateValue, gen, provider);
173169
}
174170

src/main/java/com/fasterxml/jackson/databind/ser/std/StdSerializer.java

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
import java.io.IOException;
44
import java.lang.reflect.InvocationTargetException;
55
import java.lang.reflect.Type;
6-
import java.util.HashSet;
7-
import java.util.Set;
6+
import java.util.IdentityHashMap;
7+
import java.util.Map;
88

99
import com.fasterxml.jackson.annotation.JsonFormat;
1010
import com.fasterxml.jackson.annotation.JsonInclude;
@@ -34,6 +34,14 @@ public abstract class StdSerializer<T>
3434
{
3535
private static final long serialVersionUID = 1L;
3636

37+
/**
38+
* Key used for storing a lock object to prevent infinite recursion when
39+
* constructing converting serializers.
40+
*
41+
* @since 2.9
42+
*/
43+
private final static Object KEY_CONTENT_CONVERTER_LOCK = new Object();
44+
3745
/**
3846
* Nominal type supported, usually declared type of
3947
* property for which serializer is used.
@@ -355,30 +363,29 @@ protected JsonSerializer<?> findContextualConvertingSerializer(SerializerProvide
355363
{
356364
// 08-Dec-2016, tatu: to fix [databind#357], need to prevent recursive calls for
357365
// same property
358-
/*
359366
@SuppressWarnings("unchecked")
360-
Set<Object> conversions = (Set<Object>) provider.getAttribute(CONTENT_CONVERTER_LOCK);
367+
Map<Object,Object> conversions = (Map<Object,Object>) provider.getAttribute(KEY_CONTENT_CONVERTER_LOCK);
361368
if (conversions != null) {
362-
if (conversions.contains(property)) {
369+
Object lock = conversions.get(property);
370+
if (lock != null) {
363371
return existingSerializer;
364372
}
365373
} else {
366-
conversions = new HashSet<>();
367-
provider.setAttribute(CONTENT_CONVERTER_LOCK, provider);
374+
conversions = new IdentityHashMap<>();
375+
provider.setAttribute(KEY_CONTENT_CONVERTER_LOCK, conversions);
368376
}
377+
conversions.put(property, Boolean.TRUE);
369378
try {
370-
} finally {
371-
}
372-
*/
373379
JsonSerializer<?> ser = findConvertingContentSerializer(provider, property, existingSerializer);
374380
if (ser != null) {
375381
return provider.handleSecondaryContextualization(ser, property);
376382
}
383+
} finally {
384+
conversions.remove(property);
385+
}
377386
return existingSerializer;
378387
}
379388

380-
// private final static Object CONTENT_CONVERTER_LOCK = new Object();
381-
382389
/**
383390
* @deprecated Since 2.9 use {link {@link #findContextualConvertingSerializer} instead
384391
*/

src/test/java/com/fasterxml/jackson/databind/convert/TestConvertingDeserializer.java

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import java.util.*;
55

66
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
7+
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
78
import com.fasterxml.jackson.databind.util.StdConverter;
89

910
public class TestConvertingDeserializer
@@ -99,6 +100,21 @@ static class LowerCaseTextArray {
99100
public String[] texts;
100101
}
101102

103+
// [databind#357]
104+
static class Value { }
105+
106+
static class ListWrapper {
107+
@JsonSerialize(contentConverter = ValueToStringListConverter.class)
108+
public List<Value> list = Arrays.asList(new Value());
109+
}
110+
111+
static class ValueToStringListConverter extends StdConverter<Value, List<String>> {
112+
@Override
113+
public List<String> convert(Value value) {
114+
return Arrays.asList("Hello world!");
115+
}
116+
}
117+
102118
// for [databind#795]
103119

104120
static class ToNumberConverter extends StdConverter<String,Number>
@@ -114,7 +130,7 @@ static class Issue795Bean
114130
@JsonDeserialize(converter=ToNumberConverter.class)
115131
public Number value;
116132
}
117-
133+
118134
/*
119135
/**********************************************************
120136
/* Test methods
@@ -198,6 +214,12 @@ public void testPropertyAnnotationForMaps() throws Exception
198214
assertEquals(2, p.y);
199215
}
200216

217+
// [databind#357]
218+
public void testConverterForList357() throws Exception {
219+
String json = objectWriter().writeValueAsString(new ListWrapper());
220+
assertEquals("{\"list\":[[\"Hello world!\"]]}", json);
221+
}
222+
201223
// [databind#795]
202224
public void testConvertToAbstract() throws Exception
203225
{

src/test/java/com/fasterxml/jackson/failing/ConvertingSerializer357Test.java

Lines changed: 0 additions & 38 deletions
This file was deleted.

0 commit comments

Comments
 (0)