Skip to content
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

android-record: Support deserializing polymorphic members of records #249

Merged
merged 4 commits into from
Aug 15, 2024

Conversation

HelloOO7
Copy link
Contributor

This fixes #248 (see tests). As far as I could tell, the non-default ValueInstantiators do not have access to a DeserializationContext when created, so there's a fair bit of redundancy in place when using createContextual instead.

@eranl
Copy link
Contributor

eranl commented Jul 27, 2024

Thank you. LGTM. @cowtowncoder, your thougths?

@cowtowncoder
Copy link
Member

First of all, thank you @HelloOO7 !

Correct, context is passed via createContextual() same as is done for serializers and deserializers (for (de)serializers the reason are cyclic types, cycles cannot be resolved otherwise; and probably same is true for ValueInstantiator).

Code looks ok, although somehow it feels like this should be doable via JsonDeserializer side, and not on ValueInstantiator, similar to how regular JDK Record deserializer creation works.
But there may be reasons why this is not doable (jackson-databind might have access to something modules don't, for example).

Now: I really want to go through this in more detail, then merge, but am leaving for a vacation today. But will pick this up once I return in 2 weeks.
So don't worry when you won't here much until then -- this is one of top-5 items for me to do before 2.18.0-rc1 is finalized.

@HelloOO7
Copy link
Contributor Author

somehow it feels like this should be doable via JsonDeserializer side, and not on ValueInstantiator

I expanded upon ValueInstantiator in effort to adhere to the spirit of the original implementation. I may be wrong here, but wouldn't using JsonDeserializer needlessly couple the Android record module to the JSON format?

Upon looking into this further, I came up with a more similar-to-JDK approach to Android records that uses an AnnotationIntrospector, see here: https://github.com/HelloOO7/jackson-modules-base/tree/android-records-2
This approach is based on the fact that POJOPropertiesCollector handles records in _addCreators using:

if (_isRecordType) {
    primary = JDK14Util.findCanonicalRecordConstructor(_config, _classDef, constructors);
} else {
    primary = _annotationIntrospector.findDefaultCreator(_config, _classDef,
    constructors, factories);
}

However, this fails the testDeserializeSimpleRecord_DisableAnnotationIntrospector test (for apparent reasons). If that is a problem, it could probably be solved by overriding _addCreators itself in the POJOPropertiesCollector that the module overrides either way. It might also be of note that this change fixes 2 of the failing tests.

@cowtowncoder
Copy link
Member

I added included test in core jackson-databind to make sure it works with "real" Records as well (there was one test class for @JsonTypeInfo annotated members but coverage pretty slim).

Will try to get this reviewed now.

@cowtowncoder
Copy link
Member

but wouldn't using JsonDeserializer needlessly couple the Android record module to the JSON format?

No, despite its name, JsonDeserializer is format agnostic (really should be ValueDeserializer).

@cowtowncoder
Copy link
Member

@HelloOO7 I like the looks of the alternate take -- could you do a PR for that instead, and I can get it quickly reviewed?

And yes, now that I looked at the original implementation it makes sense that you extended ValueInstantiator approach. But I much prefer AnnotationIntrospector approach, esp. with 2.18 addition of findDefaultCreator.

@HelloOO7
Copy link
Contributor Author

Sure. Would it be okay to merge the new commits to the main branch of my fork and update this PR, or should I submit a new one?

@cowtowncoder
Copy link
Member

@HelloOO7 Either way is fine, whatever is easiest to do?

@HelloOO7
Copy link
Contributor Author

Alright, I merged it to my branch of 2.18. It's now awaiting review as part of this PR as far as I can see (commit has appeared before my last message probably 'cause it's sorted chronologically).

@HelloOO7
Copy link
Contributor Author

I reckon I should probably update the tests to no longer be in the failing package, if this approch is the way to go forward.

@cowtowncoder cowtowncoder merged commit 0779111 into FasterXML:2.18 Aug 15, 2024
4 checks passed
@cowtowncoder
Copy link
Member

Hmmmh. I wish indentation was not changed -- merging this into master (3.0) is pretty painful due to bogus changes... :-(

@cowtowncoder
Copy link
Member

Thank you @HelloOO7 -- now merged in 2.18 for 2.18.0 as well as master for eventual 3.0.0.

@HelloOO7
Copy link
Contributor Author

Oh well. I tried to configure it to keep 2 spaces indentation (which I think it did), but the tests had strangely nested static classes on a different indentation level than static methods, which my IDE couldn't keep up with:( Sorry.

@HelloOO7
Copy link
Contributor Author

I'm really looking forward to have this fixed in 2.18. It's gonna be nice not to have to bother with workarounds. Thank you too!

@cowtowncoder
Copy link
Member

@HelloOO7 yeah np, indentation gets tricky no worries. Glad to have gotten it all merged.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

jClass annotations and polymorphic types are ignored when deserializing Android Record fields
3 participants