Include.NON_DEFAULT regression for objects with @JsonValue
Search before asking
- [x] I searched in the issues and found nothing similar.
Describe the bug
Classes which use @JsonValue
and use values which would result in empty string
and are used as fields in serializable Pojos,
and Object mapper is configured with Include.NON_DEFAULT
will result in different json values starting with version 2.18
Following test case will work fine in version 2.17.3, but will fail after upgrading to 2.18+
Note, this might be related to https://github.com/FasterXML/jackson-databind/issues/4741 https://github.com/FasterXML/jackson-databind/issues/4464
Version Information
2.18+
Reproduction
package com.example;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonValue;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.cfg.MutableConfigOverride;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import static com.fasterxml.jackson.annotation.JsonInclude.Include.NON_DEFAULT;
import static com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL;
public class JacksonTest {
record StringValue(String value) {
@Override
@JsonValue
public String value() {
return value;
}
}
record Pojo1(StringValue value) {
}
@JsonInclude(JsonInclude.Include.NON_DEFAULT)
record Pojo2(StringValue value) {
}
record Pojo3(@JsonInclude(JsonInclude.Include.NON_DEFAULT) StringValue value) {
}
@Test
void testSerialization() {
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.setSerializationInclusion(NON_DEFAULT);
//might be relevant for analysis, but does not affect test outcome
MutableConfigOverride objectStringConfigOverride = objectMapper.configOverride(String.class);
objectStringConfigOverride.setIncludeAsProperty(JsonInclude.Value.construct(NON_NULL, NON_NULL));
Assertions.assertAll(
//FAIL on jackson 2.18.2 / 2.20.0
() -> Assertions.assertEquals("{\"value\":\"\"}", objectMapper.writeValueAsString(new Pojo1(new StringValue("")))),
//PASS
() -> Assertions.assertEquals("{\"value\":\"\"}", objectMapper.writeValueAsString(new Pojo2(new StringValue("")))),
//FAIL on jackson 2.18.2 / 2.20.0
() -> Assertions.assertEquals("{\"value\":\"\"}", objectMapper.writeValueAsString(new Pojo3(new StringValue(""))))
);
}
}
Expected behavior
After serialization jackson should produce the same value
Additional context
No response
Could be regression off of introspection refactor which happened in 2.18. Will look in to it.
Did u find anything that could relate to this issue release-notes? @LSwiatek
Value of NON_DEFAULT has been problematic for the longest time, unfortunately.
I do not think there has been intentional changes, for what that is worth. But handling of Creators (and due to that, Record types) was rewritten for 2.18.0, with many follow-up fixes in 2.18.x patches, are likely reason for change.
Also good to verify problem remains in 2.19.2 / 2.20.0 (I assume it does but just in case).
Yup, failing 2.18 and onward (including 2.x latest)
@LSwiatek Have you found any work-around?
no, and i also found one more issue with @JsonValue which might be related
https://github.com/FasterXML/jackson-databind/issues/5380