Skip to content

Commit 9997606

Browse files
committed
Merge branch '2.10'
2 parents affb3e8 + 985ee58 commit 9997606

File tree

5 files changed

+62
-81
lines changed

5 files changed

+62
-81
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: 41 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -219,16 +219,10 @@ protected JsonSerializer<?> _createSerializer2(SerializerProvider ctxt,
219219
// And this is where this class comes in: if type is not a
220220
// known "primary JDK type", perhaps it's a bean? We can still
221221
// get a null, if we can't find a single suitable bean property.
222-
ser = findBeanSerializer(ctxt, beanDesc, type, formatOverrides);
222+
ser = constructBeanOrAddOnSerializer(ctxt, type, beanDesc, formatOverrides, staticTyping);
223223
// Finally: maybe we can still deal with it as an implementation of some basic JDK interface?
224224
if (ser == null) {
225-
ser = findSerializerByAddonType(ctxt, type, beanDesc, formatOverrides, staticTyping);
226-
// 18-Sep-2014, tatu: Actually, as per [jackson-databind#539], need to get
227-
// 'unknown' serializer assigned earlier, here, so that it gets properly
228-
// post-processed
229-
if (ser == null) {
230-
ser = ctxt.getUnknownTypeSerializer(beanDesc.getBeanClass());
231-
}
225+
ser = ctxt.getUnknownTypeSerializer(beanDesc.getBeanClass());
232226
}
233227
}
234228
}
@@ -242,43 +236,31 @@ protected JsonSerializer<?> _createSerializer2(SerializerProvider ctxt,
242236
return ser;
243237
}
244238

245-
/*
246-
/**********************************************************************
247-
/* Other public methods that are not part of `SerializerFactory` API
248-
/**********************************************************************
249-
*/
250-
251-
/**
252-
* Method that will try to construct a {@link BeanSerializer} for
253-
* given class. Returns null if no properties are found.
254-
*/
255-
public JsonSerializer<Object> findBeanSerializer(SerializerProvider ctxt, BeanDescription beanDesc,
256-
JavaType type, JsonFormat.Value format)
257-
throws JsonMappingException
258-
{
259-
// First things first: we know some types are not beans...
260-
if (!isPotentialBeanType(type.getRawClass())) {
261-
// Except we do need to allow serializers for Enums, if shape dictates (which it does
262-
// if we end up here)
263-
if (!type.isEnumType()) {
264-
return null;
265-
}
266-
}
267-
return constructBeanSerializer(ctxt, beanDesc);
268-
}
269-
270239
/*
271240
/**********************************************************************
272241
/* Overridable non-public factory methods
273242
/**********************************************************************
274243
*/
275244

276245
/**
277-
* Method called to construct serializer for serializing specified bean type.
246+
* Method called to construct serializer based on checking which condition is matched:
247+
* <ol>
248+
* <li>Nominal type is {@code java.lang.Object}: if so, return special "no type known" serializer
249+
* </li>
250+
* <li>If a known "not-POJO" type (like JDK {@code Proxy}), return {@code null}
251+
* </li>
252+
* <li>If at least one logical property found, build actual {@code BeanSerializer}
253+
* </li>
254+
* <li>If add-on type (like {@link java.lang.Iterable}) found, create appropriate serializer
255+
* </li>
256+
* <li>If one of Jackson's "well-known" annotations found, create bogus "empty Object" Serializer
257+
* </li>
258+
* </ol>
259+
* or, if none matched, return {@code null}.
278260
*/
279261
@SuppressWarnings("unchecked")
280-
protected JsonSerializer<Object> constructBeanSerializer(SerializerProvider ctxt,
281-
BeanDescription beanDesc)
262+
protected JsonSerializer<Object> constructBeanOrAddOnSerializer(SerializerProvider ctxt,
263+
JavaType type, BeanDescription beanDesc, JsonFormat.Value format, boolean staticTyping)
282264
throws JsonMappingException
283265
{
284266
// 13-Oct-2010, tatu: quick sanity check: never try to create bean serializer for plain Object
@@ -287,6 +269,16 @@ protected JsonSerializer<Object> constructBeanSerializer(SerializerProvider ctxt
287269
return ctxt.getUnknownTypeSerializer(Object.class);
288270
// throw new IllegalArgumentException("Cannot create bean serializer for Object.class");
289271
}
272+
273+
// We also know some types are not beans...
274+
if (!isPotentialBeanType(type.getRawClass())) {
275+
// Except we do need to allow serializers for Enums, if shape dictates (which it does
276+
// if we end up here)
277+
if (!type.isEnumType()) {
278+
return null;
279+
}
280+
}
281+
290282
final SerializationConfig config = ctxt.getConfig();
291283
BeanSerializerBuilder builder = constructBeanSerializerBuilder(beanDesc);
292284
builder.setConfig(config);
@@ -329,18 +321,18 @@ protected JsonSerializer<Object> constructBeanSerializer(SerializerProvider ctxt
329321

330322
AnnotatedMember anyGetter = beanDesc.findAnyGetter();
331323
if (anyGetter != null) {
332-
JavaType type = anyGetter.getType();
324+
JavaType anyType = anyGetter.getType();
333325
// copied from BasicSerializerFactory.buildMapSerializer():
334-
boolean staticTyping = config.isEnabled(MapperFeature.USE_STATIC_TYPING);
335-
JavaType valueType = type.getContentType();
326+
JavaType valueType = anyType.getContentType();
336327
TypeSerializer typeSer = ctxt.findTypeSerializer(valueType);
337328
// last 2 nulls; don't know key, value serializers (yet)
338329
// 23-Feb-2015, tatu: As per [databind#705], need to support custom serializers
339330
JsonSerializer<?> anySer = findSerializerFromAnnotation(ctxt, anyGetter);
340331
if (anySer == null) {
341332
// TODO: support '@JsonIgnoreProperties' with any setter?
342333
anySer = MapSerializer.construct(/* ignored props*/ (Set<String>) null,
343-
type, staticTyping, typeSer, null, null, /*filterId*/ null);
334+
anyType, config.isEnabled(MapperFeature.USE_STATIC_TYPING),
335+
typeSer, null, null, /*filterId*/ null);
344336
}
345337
// TODO: can we find full PropertyName?
346338
PropertyName name = PropertyName.construct(anyGetter.getName());
@@ -366,11 +358,15 @@ protected JsonSerializer<Object> constructBeanSerializer(SerializerProvider ctxt
366358
beanDesc.getType(), e.getClass().getName(), e.getMessage());
367359
}
368360
if (ser == null) {
369-
// If we get this far, there were no properties found, so no regular BeanSerializer
370-
// would be constructed. But, couple of exceptions.
371-
// First: if there are known annotations, just create 'empty bean' serializer
372-
if (beanDesc.hasKnownClassAnnotations()) {
373-
return builder.createDummy();
361+
// [databind#2390]: Need to consider add-ons before fallback "empty" serializer
362+
ser = (JsonSerializer<Object>) findSerializerByAddonType(ctxt, type, beanDesc, format, staticTyping);
363+
if (ser == null) {
364+
// If we get this far, there were no properties found, so no regular BeanSerializer
365+
// would be constructed. But, couple of exceptions.
366+
// First: if there are known annotations, just create 'empty bean' serializer
367+
if (beanDesc.hasKnownClassAnnotations()) {
368+
return builder.createDummy();
369+
}
374370
}
375371
}
376372
return ser;

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

Lines changed: 2 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
import com.fasterxml.jackson.annotation.JsonTypeInfo.As;
1010
import com.fasterxml.jackson.annotation.JsonTypeInfo.Id;
1111
import com.fasterxml.jackson.databind.*;
12-
import com.fasterxml.jackson.databind.ser.BeanSerializerFactory;
1312
import com.fasterxml.jackson.databind.testutil.NoCheckSubTypeValidator;
1413

1514
public class TestWithGenerics extends BaseMapTest
@@ -96,22 +95,8 @@ public void resolve(SerializerProvider provider) throws JsonMappingException
9695
beanSerializer.resolve(provider);
9796
}
9897
}
99-
100-
@SuppressWarnings("serial")
101-
protected static class CustomJsonSerializerFactory extends BeanSerializerFactory
102-
{
103-
public CustomJsonSerializerFactory() { super(null); }
104-
105-
@Override
106-
protected JsonSerializer<Object> constructBeanSerializer(SerializerProvider prov,
107-
BeanDescription beanDesc)
108-
throws JsonMappingException
109-
{
110-
return new CustomJsonSerializer(super.constructBeanSerializer(prov, beanDesc) );
111-
}
112-
}
11398

114-
// [Issue#543]
99+
// [databind#543]
115100
static class ContainerWithTwoAnimals<U extends Animal,V extends Animal> extends ContainerWithField<U> {
116101
public V otherAnimal;
117102

@@ -195,25 +180,7 @@ public void testJackson387() throws Exception
195180
assertEquals(4, mc2.params.size());
196181
}
197182

198-
public void testJackson430() throws Exception
199-
{
200-
// om.getSerializationConfig().setSerializationInclusion( Inclusion.NON_NULL );
201-
ObjectMapper om = jsonMapperBuilder()
202-
.serializerFactory(new CustomJsonSerializerFactory())
203-
.build();
204-
MyClass mc = new MyClass();
205-
mc.params.add(new MyParam<Integer>(1));
206-
207-
String str = om.writeValueAsString( mc );
208-
// System.out.println( str );
209-
210-
MyClass mc2 = om.readValue( str, MyClass.class );
211-
assertNotNull(mc2);
212-
assertNotNull(mc2.params);
213-
assertEquals(1, mc2.params.size());
214-
}
215-
216-
// [Issue#543]
183+
// [databind#543]
217184
public void testValueWithMoreGenericParameters() throws Exception
218185
{
219186
WrappedContainerWithField wrappedContainerWithField = new WrappedContainerWithField();

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
@@ -168,4 +173,11 @@ public void testIterable358() throws Exception {
168173
String json = MAPPER.writeValueAsString(new B());
169174
assertEquals("{\"list\":[[\"Hello world.\"]]}", json);
170175
}
176+
177+
// [databind#2390]
178+
public void testIterableWithAnnotation() throws Exception
179+
{
180+
assertEquals("[1,2,3]",
181+
STATIC_MAPPER.writeValueAsString(new IntIterable2390()));
182+
}
171183
}

0 commit comments

Comments
 (0)