Description
When customizing Jackson's ObjectMapper via Jackson2ObjectMapperBuilderCustomizer
in Spring Boot, attempting to configure JsonReadFeatures
like below causes IllegalArgumentException
:
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
@Slf4j
@AutoConfiguration(before = JacksonAutoConfiguration.class)
public class JacksonConfig {
@Bean
private Jackson2ObjectMapperBuilderCustomizer customize() {
return builder -> {
builder.featuresToEnable(JsonReadFeature.ALLOW_SINGLE_QUOTES);
builder.featuresToEnable(JsonWriteFeature.WRITE_NUMBERS_AS_STRINGS);
builder.featuresToEnable(StreamWriteFeature.WRITE_BIGDECIMAL_AS_PLAIN);
};
}
}
This is because Jackson2ObjectMapperBuilder currently only supports configuring a limited set of feature types including JsonParser.Feature, JsonGenerator.Feature, SerializationFeature, DeserializationFeature and MapperFeature.
But JsonReadFeature, JsonWriteFeature, StreamWriteFeature introduced in Jackson 2.10 is not supported yet. So enabling it via customize() method throws exception:
IllegalArgumentException: Unknown feature class: com.fasterxml.jackson.core.json.JsonReadFeature
IllegalArgumentException: Unknown feature class: com.fasterxml.jackson.core.json.JsonWriteFeature
IllegalArgumentException: Unknown feature class: com.fasterxml.jackson.core.json.StreamWriteFeature
Root Cause
private void configureFeature(ObjectMapper objectMapper, Object feature, boolean enabled) {
if (feature instanceof JsonParser.Feature jsonParserFeature) {
objectMapper.configure(jsonParserFeature, enabled);
} else if (feature instanceof JsonGenerator.Feature jsonGeneratorFeature) {
objectMapper.configure(jsonGeneratorFeature, enabled);
} else if (feature instanceof SerializationFeature serializationFeature) {
objectMapper.configure(serializationFeature, enabled);
} else if (feature instanceof DeserializationFeature deserializationFeature) {
objectMapper.configure(deserializationFeature, enabled);
} else if (feature instanceof MapperFeature mapperFeature) {
objectMapper.configure(mapperFeature, enabled);
} else {
throw new IllegalArgumentException("Unknown feature class: " + feature.getClass().getName());
}
}
The root cause is org.springframework.http.converter.json.Jackson2ObjectMapperBuilder#configureFeature() method hardcoded checking for those feature types but not handling JsonReadFeature, JsonWriteFeature, JsonWriteFeature.
Versions
This issue occurs on latest Spring Boot 3.1.3 with Jackson 2.15.2.
Suggestion
It is suggested that Spring Framework should add support for JsonReadFeature, JsonWriteFeature, StreamWriteFeature in a future release by mapping it to corresponding MapperFeature, or identifying their parent classes like JacksonFeature
and ConfigFeature
, to maintain compatibility with latest Jackson versions when customizing ObjectMapper.
Comment From: sdeleuze
Jackson2ObjectMapperBuilder
supports what ObjectMapper#configure
supports, we can add new overloaded variants supported on more recent versions of Jackson like we did for DatatypeFeature
in #31380, but I am not sure Jackson2ObjectMapperBuilder
should do opinionated processing of features that ObjectMapper
don't support directly.
The features you mentioned seems handled on ObjectWriter
and ObjectReader
side, but not directly on ObjectMapper
if I am not mistaken since no facility is provided for FormatFeature
, StreamWriteFeature
or JacksonFeature
. Could be on purpose or not.
I would suggest to create a related issue or PR on Jackson side, in order to allow Spring to support what you ask if adding those variants make sense on Jackson side. Any thoughts?
Comment From: spring-projects-issues
If you would like us to look at this issue, please provide the requested information. If the information is not provided within the next 7 days this issue will be closed.
Comment From: spring-projects-issues
Closing due to lack of requested feedback. If you would like us to look at this issue, please provide the requested information and we will re-open the issue.