-
Notifications
You must be signed in to change notification settings - Fork 4.3k
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
Fix RuntimeTypeAdapterFactory #2139
Conversation
Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA). View this failed invocation of the CLA check for more information. For the most up to date status, view the checks section at the bottom of the pull request. |
Thanks for the proposal! Would it be possible to add a test that fails without this fix and passes with it? |
@eamonnmcmanus like this? Or in a single commit? The thing is in the existing test, the base class was explicitely given, so the bug did not occur. I just removed the explicit typeOfSrc parameter. In a real world example, the object could be a collection element or an attribute of a class being serialized, so there would be no typeOfSrc either. If it is not given, the RuntimeTypeAdapterFactory.create method does not work, because it just compares if the type matches the base-type excaclty, instead of if it is supertype. |
...btw it would be great, if the gson-extras would be released on maven somehow, because currently many people just copy the class to their source-code and won't profit from future updates. |
@@ -205,7 +205,7 @@ public RuntimeTypeAdapterFactory<T> registerSubtype(Class<? extends T> type) { | |||
|
|||
@Override | |||
public <R> TypeAdapter<R> create(Gson gson, TypeToken<R> type) { | |||
if (type.getRawType() != baseType) { | |||
if (null == type || !baseType.isAssignableFrom(type.getRawType())) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would you mind fixing the Yoda condition? i.e. type == null
instead.
Yes, I think this test change is enough. Just one style nit, which I should have mentioned before. Regarding gson-extras, I think that's an unrelated question? This project is in maintenance mode so realistically we're probably not going to be adding brand new artifacts to Maven Central. |
It does work if the field type or collection element type is the base type. Consider the following class: static class Test {
Base base;
Sub sub;
List<Base> baseList;
List<Sub> subList;
} When creating an instance of So even if the behavior was originally intended to be like this, it might be good nonetheless to change it, as done in this PR. |
Trying to use this class as is results in the type-property not being serialized into the JSON, thus it is not present on deserialization. The fix from google#712 (comment) works. No idea why this is not merged yet.
@eamonnmcmanus I inverted the null check. @Marcono1234 I am not sure if I understand, but I had the error when trying to expliciteley serialize a list of the base-class, so this was definitely a bug IMHO. Could you maybe create an example? If the serialization does not add the type field, the deserialization will fail. And if it adds the field, the deserialization will remove it, so I do not see the redundancy. @eamonnmcmanus is only the extras on maintenance mode or the whole GSON project? Why? Are the receommended alternatives? |
What I meant was when serializing as Regarding the tests, what I meant was that it should ideally cover both:
Your changes modify the tests to only cover However, I am not a member of this project so unlike eamonnmcmanus' comments feel free to consider mine only as suggestions. |
The whole project. It is fine for people to continue using Gson but for new projects I would probably recommend Moshi. |
FYI this change caused problems at Google, where we do in fact use the |
…lly. (#2160) PR #2139 changed this factory so that if given a certain baseType, it will also recognize any subtype of that type. That is often the right thing to do, but it is a change in behaviour, and does in fact break at least one current client of this code. So instead we introduce a new `recognizeSubclasses()` method that triggers this behaviour. When the method is not called, we revert to the old behaviour of only recognizing instances of the exact class `baseType`.
Ok. Thanks for the heads up. I'm sorry this introduced errors, but with your |
Trying to use this class as is results in the type-property not being serialized into the JSON, thus it is not present on deserialization.
The fix from #712 (comment) works. No idea why this is not merged yet.