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

Support serialization of Iterator and Stream #597

Merged
merged 6 commits into from
May 22, 2023

Conversation

JooHyukKim
Copy link
Member

@JooHyukKim JooHyukKim commented May 13, 2023

Class<?> cls = type.getRawClass();
if (type.isContainerType()
|| Iterator.class.isAssignableFrom(cls)
|| Stream.class.isAssignableFrom(cls)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this needed? I'd have expected Iterator and Stream to have JavaTypes that are container types.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, neither of them are container types :/

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@cowtowncoder would isCollectionLikeType() something that could be considered here? isContainerType() does not include Streams and Iterators. Since we have a JavaType instance here, it would be nice not to have to hardcode the classes.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Last time I checked Iterator and Stream return false with isCollectionLikeType(). I will double check and return shortly.

it would be nice not to have to hardcode the classes.

I do agree that place where we hardcod-classes will probably end up with more hardcoded-classes. But I can also think as "how many times will Java creators will add interfaces such as Iterator and Stream?"

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would isCollectionLikeType() something that could be considered here?

Or did you mean making Iterator and Stream officially CollectionLikeType, @pjfanning ?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am trying to figure out how I feel about this. I feel Iterators etc are not "Collection"-like; perhaps we could/should consider new IteratorType for 2.16? It would have element type; not sure what other commonality there should be.

Trick here (well one of them) is to figure out how Scala, Kotlin (and maybe later JDK modules) would augment information -- otherwise we could just add something in SimpleType.

For inspiration we could look into ReferenceType (or CollectionLikeType).

There could then be something like isIterableType() in JavaType returning true for Map(Like), Collection(Like), Array and IteratorTypes.

Would this be a way forward?

Copy link
Member Author

@JooHyukKim JooHyukKim May 15, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I say +1 for IteratorType.

There could then be something like isIterableType() in JavaType returning true for Map(Like), Collection(Like), Array and IteratorTypes.

Sounds like this new IteratorType will be direct superset of CollectionLikeType and MapLikeType, anything that can "return" an Iterator.
EDIT(added) : If so, my opinion is desigining this new JavaType should take longer time to design with caution.

I am worried about the name IteratorType as it might create confusion. In reality Map, Stream do not extend, or implement, but just have methods that return an Iterator. ATM I can think of names like IteratorCreatorType or IteratorLikeType 😅

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we could merge this PR as it is and then proceed with the JavaType changes independently? We can always uptake the JavaType changes for this use case later.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see that @cowtowncoder made this point about the JavaType changes in another comment.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, +1 for separate approach.

As to IteratorType, could also consider IterableType (although it has same possible issue wrt naming).
Perhaps IterationType would be a better choice.

Also on MapLikeType, CollectionLikeType -- these would not be super types; Maps are not iterators (nor Collections; nor MapLike/CollectionLike). Partly since not all Map(like) types implement actual iterator/iterable (in fact, most don't).
Or put another way: in case something implements Iterator (etc) but is also Map (or Map-like), our JavaType would be Map[Like]Type. Iterator tends to be more an add-on (or mix-in) type.

@pjfanning
Copy link
Member

@JooHyukKim should we also add deserialization tests? If you feel this is too much for this PR but suspect that we do need more work on the deserialization, could you log a follow up issue?

@JooHyukKim
Copy link
Member Author

@JooHyukKim should we also add deserialization tests? If you feel this is too much for this PR but suspect that we do need more work on the deserialization, could you log a follow up issue?

@pjfanning I certainly agree we need deserialization counterpart. And yes, let's (I will) create a follow up issue, because I think this already affects broad scope 😄

@cowtowncoder
Copy link
Member

On this PR specifically, we could consider doing:

  1. Hard-coded approach for 2.15 or 2.16 initially
  2. Clean up later on if and when JavaType adds detection functionality.

@pjfanning
Copy link
Member

@JooHyukKim could you create a shared method for checking the class for these Iterator.class.isAssignableFrom(cls) || Stream.class.isAssignableFrom(cls) ?

This check appears twice so it would be good to share the check (just in case we need to add more classes to the check).

@JooHyukKim
Copy link
Member Author

@JooHyukKim could you create a shared method for checking the class for these Iterator.class.isAssignableFrom(cls) || Stream.class.isAssignableFrom(cls) ?

This check appears twice so it would be good to share the check (just in case we need to add more classes to the check).

Sure 👍🏻, Sounds great!

@JooHyukKim
Copy link
Member Author

Come to think of it, related issues have been around a long time. Should we rebase this PR agaisnt 2.15? 🤔

@pjfanning
Copy link
Member

Not a big deal but I wrote FasterXML/jackson-module-scala#636 to try out this problem with Scala Iterators and there is an issue and this fix won't help (for Scala Iterators). That doesn't mean we shouldn't proceed - it just highlights that adding a JavaType based solution in the future would be useful.

@JooHyukKim
Copy link
Member Author

To keep track of things, let's link this to FasterXML/jackson-databind#3926

}
}

public void testCollectionSerialization() throws JsonProcessingException {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's change these to throws Exception since JsonProcessingException is removed from 3.0 and JacksonException (that exists) does not extend IOException any longer.
So use of plain Exception allows cleaner merging.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great point 👍🏻👍🏻 Done

import java.util.stream.Stream;

// [dataformat-xml#302] : Unable to serialize top-level Java8 Stream
public class Jdk8StreamSerialization302Test extends XmlTestBase {
Copy link
Member Author

@JooHyukKim JooHyukKim May 21, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmmmm, Sounds like what Jdk8StreamSerialization302Test, does. Maybe move this test case there?

@cowtowncoder I was refering to this class

EDIT: Maybe the class name doesn't reflect what it really tests. Any suggestion? 🤔

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed to IterationType302Test

@JooHyukKim JooHyukKim deleted the support-stream-and-iterable branch May 24, 2023 14:48
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.

3 participants