Skip to content

Commit 152aabb

Browse files
committed
Fixed #539 in master (for 2.5.0) -- slightly risky change so can't easily backport unfortunately.
1 parent f95a927 commit 152aabb

File tree

4 files changed

+79
-29
lines changed

4 files changed

+79
-29
lines changed

release-notes/VERSION

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@ Version: 2.5.0 (xx-xxx-2014)
44
#521: Keep bundle annotations, prevent problems with recursive annotation
55
types
66
(reported by tea-dragon@github)
7+
#539: Problem with post-procesing of "empty bean" serializer; was not calling
8+
'BeanSerializerModifier.modifySerializer()` for empty beans
9+
(reported by Fabien R, fabienrenaud@github)
710
#543: Problem resolving self-referential recursive types
811
(reported by ahgittin@github)
912

src/main/java/com/fasterxml/jackson/databind/SerializerProvider.java

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -745,6 +745,17 @@ public JsonSerializer<Object> getUnknownTypeSerializer(Class<?> unknownType) {
745745
return _unknownTypeSerializer;
746746
}
747747

748+
/**
749+
* Helper method called to see if given serializer is considered to be
750+
* something returned by {@link #getUnknownTypeSerializer}, that is, something
751+
* for which no regular serializer was found or constructed.
752+
*
753+
* @since 2.5
754+
*/
755+
public boolean isUnknownTypeSerializer(JsonSerializer<?> ser) {
756+
return (ser == _unknownTypeSerializer) || (ser == null);
757+
}
758+
748759
/*
749760
/**********************************************************
750761
/* Methods for creating instances based on annotations
@@ -987,19 +998,26 @@ protected void _reportIncompatibleRootType(Object value, JavaType rootType)
987998
* @return Serializer if one can be found, null if not.
988999
*/
9891000
protected JsonSerializer<Object> _findExplicitUntypedSerializer(Class<?> runtimeType)
990-
throws JsonMappingException
1001+
throws JsonMappingException
9911002
{
9921003
// Fast lookup from local lookup thingy works?
9931004
JsonSerializer<Object> ser = _knownSerializers.untypedValueSerializer(runtimeType);
994-
if (ser != null) {
995-
return ser;
996-
}
997-
// If not, maybe shared map already has it?
998-
ser = _serializerCache.untypedValueSerializer(runtimeType);
999-
if (ser != null) {
1000-
return ser;
1005+
if (ser == null) {
1006+
// If not, maybe shared map already has it?
1007+
ser = _serializerCache.untypedValueSerializer(runtimeType);
1008+
if (ser == null) {
1009+
ser = _createAndCacheUntypedSerializer(runtimeType);
1010+
/* 18-Sep-2014, tatu: This is unfortunate patch over related change
1011+
* that pushes creation of "unknown type" serializer deeper down
1012+
* in BeanSerializerFactory; as a result, we need to "undo" creation
1013+
* here.
1014+
*/
1015+
if (isUnknownTypeSerializer(ser)) {
1016+
return null;
1017+
}
1018+
}
10011019
}
1002-
return _createAndCacheUntypedSerializer(runtimeType);
1020+
return ser;
10031021
}
10041022

10051023
/*

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

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,12 @@ protected JsonSerializer<?> _createSerializer2(SerializerProvider prov,
223223
// Finally: maybe we can still deal with it as an implementation of some basic JDK interface?
224224
if (ser == null) {
225225
ser = findSerializerByAddonType(config, type, beanDesc, 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 = prov.getUnknownTypeSerializer(beanDesc.getBeanClass());
231+
}
226232
}
227233
}
228234
}
@@ -403,14 +409,10 @@ protected JsonSerializer<Object> constructBeanSerializer(SerializerProvider prov
403409

404410
JsonSerializer<Object> ser = (JsonSerializer<Object>) builder.build();
405411

406-
/* However, after all modifications: no properties, no serializer
407-
* (note; as per [JACKSON-670], check was moved later on from an earlier location)
408-
*/
409412
if (ser == null) {
410-
/* 27-Nov-2009, tatu: Except that as per [JACKSON-201], we are
411-
* ok with that as long as it has a recognized class annotation
412-
* (which may come from a mix-in too)
413-
*/
413+
// If we get this far, there were no properties found, so no regular BeanSerializer
414+
// would be constructed. But, couple of exceptions.
415+
// First: if there are known annotations, just create 'empty bean' serializer
414416
if (beanDesc.hasKnownClassAnnotations()) {
415417
return builder.createDummy();
416418
}

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

Lines changed: 40 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55

66
import com.fasterxml.jackson.annotation.*;
77
import com.fasterxml.jackson.core.*;
8-
98
import com.fasterxml.jackson.databind.*;
109
import com.fasterxml.jackson.databind.introspect.AnnotatedField;
1110
import com.fasterxml.jackson.databind.introspect.POJOPropertyBuilder;
@@ -26,17 +25,11 @@
2625
@SuppressWarnings("serial")
2726
public class TestBeanSerializer extends BaseMapTest
2827
{
29-
/*
30-
/********************************************************
31-
/* Helper types
32-
/********************************************************
33-
*/
34-
35-
static class ModuleImpl extends SimpleModule
28+
static class SerializerModifierModule extends SimpleModule
3629
{
3730
protected BeanSerializerModifier modifier;
3831

39-
public ModuleImpl(BeanSerializerModifier modifier)
32+
public SerializerModifierModule(BeanSerializerModifier modifier)
4033
{
4134
super("test", Version.unknownVersion());
4235
this.modifier = modifier;
@@ -178,6 +171,24 @@ public List<BeanPropertyWriter> changeProperties(SerializationConfig config,
178171
}
179172
}
180173

174+
// [Issue#539]: use post-modifier
175+
static class EmptyBeanModifier539 extends BeanSerializerModifier
176+
{
177+
@Override
178+
public List<BeanPropertyWriter> changeProperties(SerializationConfig config,
179+
BeanDescription beanDesc, List<BeanPropertyWriter> beanProperties)
180+
{
181+
System.err.println("DEBUG: changeProperties!");
182+
return beanProperties;
183+
}
184+
185+
@Override
186+
public JsonSerializer<?> modifySerializer(SerializationConfig config,
187+
BeanDescription beanDesc, JsonSerializer<?> serializer) {
188+
System.err.println("DEBUG: modifySer!");
189+
return new BogusBeanSerializer(42);
190+
}
191+
}
181192
// [Issue#120], arrays, collections, maps
182193

183194
static class ArraySerializerModifier extends BeanSerializerModifier {
@@ -251,30 +262,30 @@ enum EnumABC { A, B, C };
251262
public void testPropertyRemoval() throws Exception
252263
{
253264
ObjectMapper mapper = new ObjectMapper();
254-
mapper.registerModule(new ModuleImpl(new RemovingModifier("a")));
265+
mapper.registerModule(new SerializerModifierModule(new RemovingModifier("a")));
255266
Bean bean = new Bean();
256267
assertEquals("{\"b\":\"b\"}", mapper.writeValueAsString(bean));
257268
}
258269

259270
public void testPropertyReorder() throws Exception
260271
{
261272
ObjectMapper mapper = new ObjectMapper();
262-
mapper.registerModule(new ModuleImpl(new ReorderingModifier()));
273+
mapper.registerModule(new SerializerModifierModule(new ReorderingModifier()));
263274
Bean bean = new Bean();
264275
assertEquals("{\"a\":\"a\",\"b\":\"b\"}", mapper.writeValueAsString(bean));
265276
}
266277

267278
public void testBuilderReplacement() throws Exception
268279
{
269280
ObjectMapper mapper = new ObjectMapper();
270-
mapper.registerModule(new ModuleImpl(new BuilderModifier(new BogusBeanSerializer(17))));
281+
mapper.registerModule(new SerializerModifierModule(new BuilderModifier(new BogusBeanSerializer(17))));
271282
Bean bean = new Bean();
272283
assertEquals("17", mapper.writeValueAsString(bean));
273284
}
274285
public void testSerializerReplacement() throws Exception
275286
{
276287
ObjectMapper mapper = new ObjectMapper();
277-
mapper.registerModule(new ModuleImpl(new ReplacingModifier(new BogusBeanSerializer(123))));
288+
mapper.registerModule(new SerializerModifierModule(new ReplacingModifier(new BogusBeanSerializer(123))));
278289
Bean bean = new Bean();
279290
assertEquals("123", mapper.writeValueAsString(bean));
280291
}
@@ -295,6 +306,22 @@ public void setupModule(SetupContext context)
295306
assertEquals("{\"bogus\":\"foo\"}", json);
296307
}
297308

309+
// [Issue#539]
310+
public void testEmptyBean539() throws Exception
311+
{
312+
ObjectMapper mapper = new ObjectMapper();
313+
mapper.registerModule(new SimpleModule("test", Version.unknownVersion()) {
314+
@Override
315+
public void setupModule(SetupContext context)
316+
{
317+
super.setupModule(context);
318+
context.addBeanSerializerModifier(new EmptyBeanModifier539());
319+
}
320+
});
321+
String json = mapper.writeValueAsString(new EmptyBean());
322+
assertEquals("42", json);
323+
}
324+
298325
// [Issue#121]
299326

300327
public void testModifyArraySerializer() throws Exception

0 commit comments

Comments
 (0)