-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Jackson Behavior Change involving AUTO_DETECT_GETTERS from 2.7.4 to 2.7.5 #1739
Comments
I can not say off-hand what is happening here, as it seems like code should work and set properties. First, when debugging, it makes sense to remove/disable:
since it typically masks all kinds of problems. It may make sense in production as defensive setting, but I have noticed that in many cases it hinders troubleshooting. As to Now: in theory it does not affect auto-discovery of setters or fields (to use for setting value). I'll have a look to see if I can find more about this. |
Looks like fields are not discovered indeed; changing them to |
Thanks @cowtowncoder for taking a look I tried removing the
I started with the failure on production and started removing the unnecessary part, until I got this smaller reproducible steps. |
Yes. I can now reproduce the problem, and I think it is valid bug. |
Thanks @cowtowncoder . For us it would be better if we can get it on top of 2.8.X . If I understand correctly 2.9.X is a new version under development with lot more features. But I understand your concern too. If the fix has narrower scope, then we can try it on 2.8.X . Also I would be happy to validate the fix against our code base once some form of fix is available. |
Actually I think I'll have to change my assessment here. Since the default visibility for fields is not "any fields" but rather "only public fields", what happens here is according to logic -- private fields are not visible, and could only be surfaced if there are visible accessors (getters). When those do not exist, fields are not included. It would be better if there was a way to indicate different visibility level for serialization/deserialization since typically one does NOT want to expose non-public field serialization (as getters), but MAY want them for deserialization (as setters). But as things are there is no way to make such distinction. As to handling of your use case I think the main options are:
|
@cowtowncoder let me summarize my understanding to see if I got the issue correctly. Jackson does auto discovery of fields to see which ones to be set on de-serialization. By default it is public fields, but if there are getters, those fields will be included too. But by disabling the auto getters, now it falls back only to public fields. Is my understanding correct ? Also this worked until 2.7.4 ( because AUTO_DETECT_GETTERS was ignored). In 2.7.5 this got fixed which broke the behavior. If my understanding is correct, I am inclined to NOT DISABLE the feature Apologies for asking too many questions, our code base is large and would love to go with least risky option. Most of the cases you mentioned recommended annotating the classes, but I am worried about classes without unit tests, which will be tricky. |
Apologies for the reping @cowtowncoder . Can you please confirm whether my understanding is correct. |
@athirupathisc Yes, your understanding is correct. One additional relevant aspect is
added in 2.2, enabled by default, which controls this behavior. I don't think it matters for your use case, but disabling of this feature would prevent this "pulling in" of setter/field-for-setting. And yes, I think you either want to keep |
@cowtowncoder I tried enabling the AUTO_DETECT_GETTERS and here is what I observed. Previously the behavior was when AUTO_DETECT_GETTERS was disabled, serialization did not call the getters method for serialization. But de-serialization still inferred those properties were there so was able to deserialize them correctly. Here are my other observations as well, just for the confirmation.
Please correct me if my understanding is correct. |
Ok, some notes:
I am not sure, however, why naming did not match between fields and getters -- in your examples they did match. So this seems odd. One aspect that has not been handled well, I admit, is the ambiguity for fields as accessor. I hope this makes more sense. |
At this point I think Jackson's behavior is actually consistent with how things should work -- deserialization fails because there are neither auto-discoverable mutators (fields or setters) nor explicit annotated ones (with |
Thanks @cowtowncoder you are right, jackson's behavior was expected. It was just unfortunate that we relied on a buggy behavior. I am making efforts to cleanup our code base. Thanks for following through. I agree that closing is the right choice. |
@athirupathisc Right, it is unfortunate to have bugs that happen to work in a way that is good for a use case. There are also many one-off convenience features that are not exactly well specified so it really is difficult to know which is which. |
The following code
When run against 2.7.4 it prints the correct de-serialized values
{alice=Saved true version 1}
When run against 2.7.5 it prints this
{alice=Saved null version null}
if AUTO_DETECT_GETTERS is not used, all version works fine.
I tried all recent versions (2.8.* ,2.9) and all of them exhibit this issue.
On looking through the issues , this could be a regression from the following code change
#1223
I am not familiar with AUTO_DETECT_GETTERS, so Please do not hesitate to point me to a document/tutorial
where I can learn more about that. If this behavior change by design,
can you please let me know how can I identify all such instances in my code base and how should I fix them.
( we have 500+ objects that are deserialized and persisted in database, so backward compat is important).
Our Application runs on Google AppEngine so I believe getters are disabled due to sandboxing restriction.
Please let me know if you need further information. Also let me know if you would prefer a
gradle project(zip file) to make the repro easier.
The text was updated successfully, but these errors were encountered: