Search before asking
- [x] I searched in the issues and found nothing similar.
Describe the bug
If there is an ImplicitPropertyName
, it seems that JsonCreator.Mode.PROPERTIES
is treated as the basis.
Version Information
Both refer to the head of the branch.
- 2.17
- 2.18
Reproduction
Comment out findImplicitPropertyName
so that it is treated as JsonCreator.Mode.DELEGATING
and the test will succeed.
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.cfg.MapperConfig;
import com.fasterxml.jackson.databind.introspect.*;
import com.fasterxml.jackson.databind.module.SimpleModule;
import org.junit.Test;
import java.util.Map;
public class GitHub846Java {
static class Dst {
private final Map<String, String> map;
Dst(Map<String, String> map) {
this.map = map;
}
public Map<String, String> getMap() {
return map;
}
}
// region: reproducing for 2.17
static class AI217 extends NopAnnotationIntrospector {
@Override
public String findImplicitPropertyName(AnnotatedMember member) {
// Hard coded as only Dst needs to be processed
if (member instanceof AnnotatedParameter) {
System.out.println(member);
System.out.println("map");
return "map";
}
return null;
}
@Override
public JsonCreator.Mode findCreatorAnnotation(MapperConfig<?> config, Annotated ann) {
if (ann instanceof AnnotatedConstructor) {
AnnotatedConstructor ac = (AnnotatedConstructor) ann;
if (ac.getParameterCount() == 1) {
System.out.println(ac);
return JsonCreator.Mode.DEFAULT;
}
}
return super.findCreatorAnnotation(config, ann);
}
}
@Test
public void test217() throws JsonProcessingException {
SimpleModule sm = new SimpleModule() {
@Override
public void setupModule(SetupContext context) {
super.setupModule(context);
context.appendAnnotationIntrospector(new AI217());
}
};
ObjectMapper mapper = new ObjectMapper().registerModule(sm);
Dst dst = mapper.readValue("{ \"key\":\"value\" }", Dst.class);
System.out.println(dst.getMap());
}
// endregion
}
Expected behavior
Given that it is not an explicit name, I felt that the treatment of both could be the same.
Additional context
This was found in a research on the following comment https://github.com/FasterXML/jackson-module-kotlin/issues/846#issuecomment-2644486029
I was not sure if this behavior is a bug, but I submitted it because if it is fixed as a bug, the above issue may be fixed at the same time.
There also seems to be a way to treat it as JsonCreator.Mode.DELEGATING
by making some changes to the reproduced code, at least in the 2.17
branch.
The 2.17
branch of kotlin-module
should be handled the same way as the reproduced code, but the test does not fail (this behavior seems to have been changed destructively in 2.18
, and https://github.com/FasterXML/jackson-module-kotlin/issues/846 is the issue that reports it).
Since it will take more time to investigate the cause of this behavior, let me first ask if the change in behavior with or without ImplicitPropertyName
is the expected behavior.
Comment From: cowtowncoder
The problem is not just the implicit name (although it is required, just not sufficient), but rather there is:
public Map<String, String> getMap() {
which makes it look very likely map
is a Property to set. So this is intentional heuristics, unfortunately.
If getter was missing (public
Field named "map" would also cause this) heuristics would not work this way.
The reason for heuristics is easier to see if we instead had, say, String name
.
I don't know why 2.17 or earlier might have worked differently.
The one question there is whether heuristics should consider type Map
(and perhaps JsonNode
) to instead imply DELEGATING.
I think this is sort of follow-up to #4911.
Comment From: cowtowncoder
Re-reading all of above, I think that the behavior of auto-detection in 2.18 is as expected: the reason PROPERTIES
mode is detected is due to implicit property name "map"
(which is sufficient without being explicitly annotated name -- although explicit would force choice without matching getter/setter/field).
Users likely should not rely on auto-detection in such case, fwtw.
Closing as "work as expected".