Open ptanov opened 4 years ago
Thank you for reporting the issue: without looking into it, sounds legit, hope to have time to look into this soon.
Thanks, take your time.
One quick note: looks like adding @JacksonInject
on field causes the problem, so a work-around is to remove it from there. I'll try to see how if there is a way to prevent unwanted injection in described case.
I can see why this occurs, and what would be needed to prevent it at high level -- injection via properties already passed via Creator should be prevented. But not sure where this could be prevented.
One quick note: looks like adding
@JacksonInject
on field causes the problem, so a work-around is to remove it from there. I'll try to see how if there is a way to prevent unwanted injection in described case.
Thank you for looking into this issue. Yes, when I remove it - everything is fine, but the problem is that in my case the constructor is autogenerated by lombok so I don't have mechanism to put the annotation in the constructor without having it on the field as described here: https://github.com/rzwitserloot/lombok/issues/1528#issuecomment-607725333
I can see why this occurs, and what would be needed to prevent it at high level -- injection via properties already passed via Creator should be prevented. But not sure where this could be prevented.
Yes, me too, that's why I didn't provided a fix. Probably we can store all already injected values in a new list here: https://github.com/FasterXML/jackson-databind/blob/jackson-databind-2.9.6/src/main/java/com/fasterxml/jackson/databind/deser/BeanDeserializer.java#L417 and then we can filter them before injecting them for the second time here: https://github.com/FasterXML/jackson-databind/blob/jackson-databind-2.9.6/src/main/java/com/fasterxml/jackson/databind/deser/BeanDeserializer.java#L217 But I'm not pretty familiar with the jackson's code and don't want to miss something, introduce wrong mechanism or broke something.
@ptanov Yeah it is tricky as deserializer themselves are stateless, so most likely I'll need to try to remove injector for non-creator properties -- I think injectors applied via creator parameters go through different route. There is unfortunate duality between "regular" properties (fields, methods) and creator properties, stemming from creator properties added later on (in jackson .... 1.5 or something). My hope is to rewrite introspection parts for Jackson 3.0 to resolve some of long-standing issues.
But I think I may be able to resolve this particular problem in 2.x without bigger rewrite.
Thank you very much for the investigation!
:+1: Thank you very much!
Actually, digging deeper into this, I am starting to think that this might not be solvable in general.
My thinking is based on realizing that @JacksonInject
is not applied into logical property, either wrt implementation (since it has to be available for fields/methods that do not acts as setter) or even logically. Rather it attaches to specific mutator (field, 1-arg method, constructor parameter) which may or may not also be mutator of a logical property.
Injectable things do not have logical name (underlying member has), so they can not be -- in all cases at least -- bundled up.
Now... I could probably solve this particular case with heuristic, however: given that field is private
AND there is annotated constructor, I could filter out specific field injection.
I think I could try that, but since it might be slightly risky, will consider for 2.12.
Thank you very much!
Hello, I have problem when using
@JacksonInject
onfinal
field that is initialized using constructor (see the whole example at the end of the message).The problem is that the correct value from JSON is used when the constructor is called, see the stacktrace:
But later this value is overrided by the default value of the injectable (but
useInput
isOptBoolean.TRUE
) because_injectables != null
atBeanDeserializer.deserialize(JsonParser, DeserializationContext, Object) line: 216
, full stacktrace:This happens even if I set
mapper.configure(MapperFeature.ALLOW_FINAL_FIELDS_AS_MUTATORS, false);
which is weired.Here is the whole example:
In my original case I'm using lombok to generate the constructor and the annotation is copied from property to the constructor parameter (you can check it here: https://github.com/rzwitserloot/lombok/issues/1528#issuecomment-607725333 ). You can check https://stackoverflow.com/a/60987798/2054634 for more information on the context of the problem.
P.S. I'm using jackson v. 2.9.6
Thanks in advance, Plamen