Skip to content

Commit 985ee58

Browse files
committed
Fix #2390
1 parent a22a18a commit 985ee58

File tree

5 files changed

+71
-32
lines changed

5 files changed

+71
-32
lines changed

release-notes/CREDITS-2.x

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -896,3 +896,7 @@ Victor Noël (victornoel@github)
896896
(2.10.0)
897897
* Reported #2339: Suboptimal return type for `ObjectNode.set()`
898898
(2.10.0)
899+
900+
Chris Mercer (cmercer@github)
901+
* Reported #2331: `JsonMappingException` through nested getter with generic wildcard return type
902+
(2.10.0)

release-notes/VERSION-2.x

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ Project: jackson-databind
88

99
#2331: `JsonMappingException` through nested getter with generic wildcard return type
1010
(reported by sunchezz89@github)
11+
#2390: `Iterable` serialization breaks when adding `@JsonFilter` annotation
12+
(reported by Chris M)
1113
#2392: `BeanDeserializerModifier.modifyDeserializer()` not applied to custom bean deserializers
1214
(reported by andreasbaus@github)
1315
#2393: `TreeTraversingParser.getLongValue()` incorrectly checks `canConvertToInt()`

src/main/java/com/fasterxml/jackson/databind/ser/BeanSerializerFactory.java

Lines changed: 48 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -228,16 +228,12 @@ protected JsonSerializer<?> _createSerializer2(SerializerProvider prov,
228228
// And this is where this class comes in: if type is not a
229229
// known "primary JDK type", perhaps it's a bean? We can still
230230
// get a null, if we can't find a single suitable bean property.
231-
ser = findBeanSerializer(prov, type, beanDesc);
232-
// Finally: maybe we can still deal with it as an implementation of some basic JDK interface?
231+
ser = findBeanOrAddOnSerializer(prov, type, beanDesc, staticTyping);
232+
// 18-Sep-2014, tatu: Actually, as per [jackson-databind#539], need to get
233+
// 'unknown' serializer assigned earlier, here, so that it gets properly
234+
// post-processed
233235
if (ser == null) {
234-
ser = findSerializerByAddonType(config, type, beanDesc, staticTyping);
235-
// 18-Sep-2014, tatu: Actually, as per [jackson-databind#539], need to get
236-
// 'unknown' serializer assigned earlier, here, so that it gets properly
237-
// post-processed
238-
if (ser == null) {
239-
ser = prov.getUnknownTypeSerializer(beanDesc.getBeanClass());
240-
}
236+
ser = prov.getUnknownTypeSerializer(beanDesc.getBeanClass());
241237
}
242238
}
243239
}
@@ -260,12 +256,23 @@ protected JsonSerializer<?> _createSerializer2(SerializerProvider prov,
260256
/**********************************************************
261257
*/
262258

259+
@Deprecated // since 2.10
260+
public JsonSerializer<Object> findBeanSerializer(SerializerProvider prov, JavaType type,
261+
BeanDescription beanDesc)
262+
throws JsonMappingException
263+
{
264+
return findBeanOrAddOnSerializer(prov, type, beanDesc, prov.isEnabled(MapperFeature.USE_STATIC_TYPING));
265+
}
266+
263267
/**
264268
* Method that will try to construct a {@link BeanSerializer} for
265-
* given class. Returns null if no properties are found.
269+
* given class if at least one property is found, OR, if not,
270+
* one of add-on types.
271+
*<p>
272+
* NOTE: behavior changed a bit
266273
*/
267-
public JsonSerializer<Object> findBeanSerializer(SerializerProvider prov, JavaType type,
268-
BeanDescription beanDesc)
274+
public JsonSerializer<Object> findBeanOrAddOnSerializer(SerializerProvider prov, JavaType type,
275+
BeanDescription beanDesc, boolean staticTyping)
269276
throws JsonMappingException
270277
{
271278
// First things first: we know some types are not beans...
@@ -276,7 +283,7 @@ public JsonSerializer<Object> findBeanSerializer(SerializerProvider prov, JavaTy
276283
return null;
277284
}
278285
}
279-
return constructBeanSerializer(prov, beanDesc);
286+
return constructBeanOrAddOnSerializer(prov, type, beanDesc, staticTyping);
280287
}
281288

282289
/**
@@ -344,14 +351,23 @@ public TypeSerializer findPropertyContentTypeSerializer(JavaType containerType,
344351
/**********************************************************
345352
*/
346353

354+
@Deprecated // since 2.10
355+
protected JsonSerializer<Object> constructBeanSerializer(SerializerProvider prov,
356+
BeanDescription beanDesc)
357+
throws JsonMappingException
358+
{
359+
return constructBeanOrAddOnSerializer(prov, beanDesc.getType(), beanDesc, prov.isEnabled(MapperFeature.USE_STATIC_TYPING));
360+
}
361+
347362
/**
348-
* Method called to construct serializer for serializing specified bean type.
363+
* Method called to construct serializer for serializing specified bean type if
364+
* (but only if, as of 2.10), at least one property is found.
349365
*
350-
* @since 2.1
366+
* @since 2.10
351367
*/
352368
@SuppressWarnings("unchecked")
353-
protected JsonSerializer<Object> constructBeanSerializer(SerializerProvider prov,
354-
BeanDescription beanDesc)
369+
protected JsonSerializer<Object> constructBeanOrAddOnSerializer(SerializerProvider prov,
370+
JavaType type, BeanDescription beanDesc, boolean staticTyping)
355371
throws JsonMappingException
356372
{
357373
// 13-Oct-2010, tatu: quick sanity check: never try to create bean serializer for plain Object
@@ -402,18 +418,18 @@ protected JsonSerializer<Object> constructBeanSerializer(SerializerProvider prov
402418

403419
AnnotatedMember anyGetter = beanDesc.findAnyGetter();
404420
if (anyGetter != null) {
405-
JavaType type = anyGetter.getType();
421+
JavaType anyType = anyGetter.getType();
406422
// copied from BasicSerializerFactory.buildMapSerializer():
407-
boolean staticTyping = config.isEnabled(MapperFeature.USE_STATIC_TYPING);
408-
JavaType valueType = type.getContentType();
423+
JavaType valueType = anyType.getContentType();
409424
TypeSerializer typeSer = createTypeSerializer(config, valueType);
410425
// last 2 nulls; don't know key, value serializers (yet)
411426
// 23-Feb-2015, tatu: As per [databind#705], need to support custom serializers
412427
JsonSerializer<?> anySer = findSerializerFromAnnotation(prov, anyGetter);
413428
if (anySer == null) {
414429
// TODO: support '@JsonIgnoreProperties' with any setter?
415430
anySer = MapSerializer.construct(/* ignored props*/ (Set<String>) null,
416-
type, staticTyping, typeSer, null, null, /*filterId*/ null);
431+
anyType, config.isEnabled(MapperFeature.USE_STATIC_TYPING),
432+
typeSer, null, null, /*filterId*/ null);
417433
}
418434
// TODO: can we find full PropertyName?
419435
PropertyName name = PropertyName.construct(anyGetter.getName());
@@ -435,15 +451,20 @@ protected JsonSerializer<Object> constructBeanSerializer(SerializerProvider prov
435451
try {
436452
ser = (JsonSerializer<Object>) builder.build();
437453
} catch (RuntimeException e) {
438-
prov.reportBadTypeDefinition(beanDesc, "Failed to construct BeanSerializer for %s: (%s) %s",
454+
return prov.reportBadTypeDefinition(beanDesc, "Failed to construct BeanSerializer for %s: (%s) %s",
439455
beanDesc.getType(), e.getClass().getName(), e.getMessage());
440456
}
441457
if (ser == null) {
442-
// If we get this far, there were no properties found, so no regular BeanSerializer
443-
// would be constructed. But, couple of exceptions.
444-
// First: if there are known annotations, just create 'empty bean' serializer
445-
if (beanDesc.hasKnownClassAnnotations()) {
446-
return builder.createDummy();
458+
// 06-Aug-2019, tatu: As per [databind#2390], we need to check for add-ons here,
459+
// before considering fallbacks
460+
ser = (JsonSerializer<Object>) findSerializerByAddonType(config, type, beanDesc, staticTyping);
461+
if (ser == null) {
462+
// If we get this far, there were no properties found, so no regular BeanSerializer
463+
// would be constructed. But, couple of exceptions.
464+
// First: if there are known annotations, just create 'empty bean' serializer
465+
if (beanDesc.hasKnownClassAnnotations()) {
466+
return builder.createDummy();
467+
}
447468
}
448469
}
449470
return ser;

src/test/java/com/fasterxml/jackson/databind/jsontype/TestWithGenerics.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -109,15 +109,15 @@ protected static class CustomJsonSerializerFactory extends BeanSerializerFactory
109109
public CustomJsonSerializerFactory() { super(null); }
110110

111111
@Override
112-
protected JsonSerializer<Object> constructBeanSerializer(SerializerProvider prov,
113-
BeanDescription beanDesc)
112+
protected JsonSerializer<Object> constructBeanOrAddOnSerializer(SerializerProvider prov,
113+
JavaType type, BeanDescription beanDesc, boolean staticTyping)
114114
throws JsonMappingException
115115
{
116-
return new CustomJsonSerializer(super.constructBeanSerializer(prov, beanDesc) );
116+
return new CustomJsonSerializer(super.constructBeanOrAddOnSerializer(prov, type, beanDesc, staticTyping) );
117117
}
118118
}
119119

120-
// [Issue#543]
120+
// [databind#543]
121121
static class ContainerWithTwoAnimals<U extends Animal,V extends Animal> extends ContainerWithField<U> {
122122
public V otherAnimal;
123123

src/test/java/com/fasterxml/jackson/databind/ser/TestIterable.java

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import java.io.IOException;
44
import java.util.*;
55

6+
import com.fasterxml.jackson.annotation.JsonFilter;
67
import com.fasterxml.jackson.core.JsonGenerator;
78

89
import com.fasterxml.jackson.databind.*;
@@ -45,7 +46,7 @@ static class BeanWithIterator {
4546

4647
public Iterator<String> getValues() { return values.iterator(); }
4748
}
48-
49+
4950
static class IntIterable implements Iterable<Integer>
5051
{
5152
@Override
@@ -99,6 +100,10 @@ public void serialize(A a, JsonGenerator jsonGenerator, SerializerProvider provi
99100
}
100101
}
101102

103+
// [databind#2390]
104+
@JsonFilter("default")
105+
static class IntIterable2390 extends IntIterable { }
106+
102107
/*
103108
/**********************************************************
104109
/* Test methods
@@ -156,4 +161,11 @@ public void testIterable358() throws Exception {
156161
String json = MAPPER.writeValueAsString(new B());
157162
assertEquals("{\"list\":[[\"Hello world.\"]]}", json);
158163
}
164+
165+
// [databind#2390]
166+
public void testIterableWithAnnotation() throws Exception
167+
{
168+
assertEquals("[1,2,3]",
169+
STATIC_MAPPER.writeValueAsString(new IntIterable2390()));
170+
}
159171
}

0 commit comments

Comments
 (0)