-
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
Add NullSafeTypeAdapter to prevent TypeAdapter.nullSafe() from returning nested null-safe type adapters (#2729) #2731
Conversation
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.
Thanks a lot!
I have added a few comments, but feel free to consider them only suggestions. Hopefully they are useful.
Also, don't worry too much about the Git history of this PR branch; the commits will be squashed on merge anyway.
} else { | ||
TypeAdapter.this.write(out, value); | ||
} | ||
if (!NullSafeTypeAdapter.class.isInstance(this)) { |
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.
Minor, but why not !(this instanceof NullSafeTypeAdapter)
?
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.
Yeah, I had instanceof
in mind, but not sure how it all works as of today. The rule org.apache.maven.enforcer.rules.version.RequireJavaVersion
fails with
Detected JDK version 21 (JAVA_HOME=/opt/.bin/jdk-21) is not in the allowed range [11,18)
If the type check is changed to !(this instanceof NullSafeTypeAdapter)
, then:
- for JDK 11, it fails with
/src/main/java/com/google/gson/TypeAdapter.java:[292,27] illegal generic type for instanceof
; - for JDK 17, it fails with
/src/main/java/com/google/gson/TypeAdapter.java:[292,16] reifiable types in instanceof are not supported in -source 7
.
The Class.instanceOf
check works for all. However, according to the source code, it can work with TypeAdapter<?>
at least in GsonBuilder
.
I seem to have some lack of the Java language knowledge. Please suggest.
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.
Ah sorry, it seems !(this instanceof NullSafeTypeAdapter)
is not possible because NullSafeTypeAdapter
is a non-static inner class (and the enclosing class TypeAdapter<T>
is generic?).
The compiler error message is really not helpful, but in Eclipse IDE the error message included the suggested fix, qualify with the enclosing type: TypeAdapter.NullSafeTypeAdapter
. Can you please try this instead?
if (!NullSafeTypeAdapter.class.isInstance(this)) { | |
if (!(this instanceof TypeAdapter.NullSafeTypeAdapter)) { |
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.
I've never encountered this error before preferring static inner classes to capture as few as possible, and now I see there are still "good-to-knows". But no doubt, isAssignable
looked really weird and unnatural. Thank you!
} | ||
|
||
private static final TypeAdapter<String> assertionErrorAdapter = | ||
new TypeAdapter<String>() { |
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.
Minor: String
can probably be omitted here since it can be inferred
new TypeAdapter<String>() { | |
new TypeAdapter<>() { |
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.
If you're really fine with changing from TypeAdapter<String>
to TypeAdapter<>
, I'll change <String>
to <>
.
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.
Minor:
String
can probably be omitted here since it can be inferred
My bad: I seem to have missed the line change I made accidentally. Also I removed the assertionErrorAdapter
TypeAdapter
type from <String>
to <>
-- I saw the diamond operator has been in use at least in this test class.
new TypeAdapter<>() { | ||
new TypeAdapter<String>() { |
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.
I think this is not needed since we compile the test code with Java 11.
Though IDEs sometimes have problems detecting this, and erroneously assume Java 7 is used for test compilation as well.
return this; | ||
} | ||
|
||
private final class NullSafeTypeAdapter extends TypeAdapter<T> { |
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.
As suggested in #2729 (comment), do you want to take the chance and implement toString
as well. I think at least some other adapters implement it, and it would then make it easier to see which adapter is wrapped by this one.
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.
Oh, I seem to have misterstood your toString()
suggestion earlier leaving it out of scope (I mistakenly assumed it leads to a stack overflow error, but it doesn't).
Could you please suggest the NullSafeTypeAdapter.toString()
pattern you'd like to see?
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.
As suggested in #2729 (comment), do you want to take the chance and implement
toString
as well. I think at least some other adapters implement it, and it would then make it easier to see which adapter is wrapped by this one.
I applied the NullSafeTypeAdapter[%s]
pattern you suggested in #2729 (comment).
And could you please edit the description of the pull request to say "Closes #2729"? Otherwise GitHub does not understand this, and will keep the issue open after merge, unless they are linked manually. |
Do you mean to add Maybe I'm misusing git but |
Yes, just edit the description of your pull request text and add that anywhere. See for example #2704 which used "Resolves #...". GitHub recognizes certain keywords and in that case will automatically close the linked issue. You can also link issue and pull request manually1, but it is easier if the creator of the pull request directly does this themselves through the keywords. Otherwise it is easy to forget manually linking the issue and pull request. That works as well if you write it in the commit message (and the commit is then merged), but personally I avoid this (unless the contribution guide of a project requests it) since for each commit this already shows in the GitHub UI for the issue a "added a commit to ... that referenced this issue" message, which can be rather distracting. So I prefer to only add it to the pull request description.
It seems that just creates a regular "mention" without having any other effect. See for example #2729 which you referenced: (No worries though about the multiple commit mentions there.) Footnotes
|
The funny thing is that I thought you meant the git commit message, not the PR description, and this is why I referenced the git-rev-list command output that produced empty result. And now I also see why it is not a good idea for GitHub, kind of shame on GitHub from this perspective. Thank you for the comprehensive explanation! |
from returning nested null-safe type adapters (#2729)
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.
@eamonnmcmanus, what do you think about this pull request?
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.
Thanks for doing this!
Add
NullSafeTypeAdapter
to preventTypeAdapter.nullSafe()
from returning nested null-safe type adapters (#2729)Purpose / Description
Resolves #2729.
Checklist
This is automatically checked by
mvn verify
, but can also be checked on its own usingmvn spotless:check
.Style violations can be fixed using
mvn spotless:apply
; this can be done in a separate commit to verify that it did not cause undesired changes.null
@since $next-version$
(
$next-version$
is a special placeholder which is automatically replaced during release)TestCase
)mvn clean verify javadoc:jar
passes without errorsCloses #2729.