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
Comment From: JooHyukKim
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
Comment From: cowtowncoder
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).
Comment From: JooHyukKim
Yup, failing 2.18 and onward (including 2.x latest)