-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Closed
Labels
2.18Issues planned at 2.18 or laterIssues planned at 2.18 or later
Description
Search before asking
- I searched in the issues and found nothing similar.
Describe the bug
For a class that wraps a Map
, registering and serializing a StdDelegatingSerializer
with a Converter
that unwraps it will throw the following error
com.fasterxml.jackson.databind.JsonMappingException: Cannot invoke "com.fasterxml.jackson.databind.JsonSerializer.serialize(Object, com.fasterxml.jackson.core.JsonGenerator, com.fasterxml.jackson.databind.SerializerProvider)" because "keySerializer" is null (through reference chain: java.util.ImmutableCollections$Map1["a"])
at com.fasterxml.jackson.databind.JsonMappingException.wrapWithPath(JsonMappingException.java:400)
at com.fasterxml.jackson.databind.JsonMappingException.wrapWithPath(JsonMappingException.java:359)
at com.fasterxml.jackson.databind.ser.std.StdSerializer.wrapAndThrow(StdSerializer.java:324)
at com.fasterxml.jackson.databind.ser.std.MapSerializer.serializeFields(MapSerializer.java:810)
at com.fasterxml.jackson.databind.ser.std.MapSerializer.serializeWithoutTypeInfo(MapSerializer.java:763)
at com.fasterxml.jackson.databind.ser.std.MapSerializer.serialize(MapSerializer.java:719)
at com.fasterxml.jackson.databind.ser.std.MapSerializer.serialize(MapSerializer.java:34)
at com.fasterxml.jackson.databind.ser.std.StdDelegatingSerializer.serialize(StdDelegatingSerializer.java:166)
at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider._serialize(DefaultSerializerProvider.java:503)
at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:342)
at com.fasterxml.jackson.databind.ObjectMapper._writeValueAndClose(ObjectMapper.java:4838)
at com.fasterxml.jackson.databind.ObjectMapper.writeValueAsString(ObjectMapper.java:4079)
at com.fasterxml.jackson.databind.Kotlin873Test.directTest(Kotlin873Test.java:61)
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
at java.base/java.lang.reflect.Method.invoke(Method.java:580)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:59)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:56)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
at org.junit.runners.BlockJUnit4ClassRunner$1.evaluate(BlockJUnit4ClassRunner.java:100)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:366)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:103)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:63)
at org.junit.runners.ParentRunner$4.run(ParentRunner.java:331)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329)
at org.junit.runners.ParentRunner.access$100(ParentRunner.java:66)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293)
at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
at org.junit.runners.ParentRunner.run(ParentRunner.java:413)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:69)
at com.intellij.rt.junit.IdeaTestRunner$Repeater$1.execute(IdeaTestRunner.java:38)
at com.intellij.rt.execution.junit.TestsRepeater.repeat(TestsRepeater.java:11)
at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:35)
at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:232)
at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:55)
Caused by: java.lang.NullPointerException: Cannot invoke "com.fasterxml.jackson.databind.JsonSerializer.serialize(Object, com.fasterxml.jackson.core.JsonGenerator, com.fasterxml.jackson.databind.SerializerProvider)" because "keySerializer" is null
at com.fasterxml.jackson.databind.ser.std.MapSerializer.serializeFields(MapSerializer.java:796)
... 34 more
Version Information
Confirmed on 2.18(7144db0) and 2.19(6729641) branches.
Reproduction
You can run it by pasting it into src/test/java/com/fasterxml/jackson/databind
.
package com.fasterxml.jackson.databind;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.module.SimpleSerializers;
import com.fasterxml.jackson.databind.ser.std.StdDelegatingSerializer;
import com.fasterxml.jackson.databind.util.StdConverter;
import org.junit.Test;
import java.util.Map;
public class Kotlin873Test {
// region: DTO Definitions
static class MapWrapper {
private final Map<String, Object> value;
MapWrapper(Map<String, Object> value) {
this.value = value;
}
public Map<String, Object> getValue() {
return value;
}
}
// endregion
// region: Jackson settings
static class WrapperConverter extends StdConverter<MapWrapper, Object> {
@Override
public Object convert(MapWrapper value) {
return value.getValue();
}
}
static class MySerializers extends SimpleSerializers {
@Override
public JsonSerializer<?> findSerializer(SerializationConfig config, JavaType type, BeanDescription beanDesc) {
Class<?> rawClass = type.getRawClass();
if (MapWrapper.class.isAssignableFrom(rawClass)) {
return new StdDelegatingSerializer(new WrapperConverter());
}
return super.findSerializer(config, type, beanDesc);
}
}
private final ObjectMapper mapper;
public Kotlin873Test() {
SimpleModule sm = new SimpleModule();
sm.setSerializers(new MySerializers());
mapper = new ObjectMapper().registerModule(sm);
}
// endregion
private final MapWrapper wrapper = new MapWrapper(Map.of("a", 1));
@Test
public void directTest() throws JsonProcessingException {
String json = mapper.writeValueAsString(wrapper);
System.out.println(json);
}
}
Expected behavior
At least it shouldn't be a NullPointerException
.
Additional context
This error can be suppressed by changing the definition of WrapperConverter
as follows to make the specification to generics concrete.
static class WrapperConverter extends StdConverter<MapWrapper, Map<String, Object>> {
@Override
public Map<String, Object> convert(MapWrapper value) {
return value.getValue();
}
}
This was not done because I was trying to reproduce a problem that had been reported to kotlin-module
.
cowtowncoder
Metadata
Metadata
Assignees
Labels
2.18Issues planned at 2.18 or laterIssues planned at 2.18 or later