jsr367-experts@jsonb-spec.java.net

[jsr367-experts] Re: [jsonb-spec users] Re: Re: Polymorphic deserializer

From: Roman Grigoriadi <roman.grigoriadi_at_oracle.com>
Date: Tue, 10 May 2016 17:25:47 +0200

Ok, I think I finally got what you mean now. Deserializer reentrance is
disabled only for the same type as current level type.

Thank you,
Roman

On 05/10/2016 05:15 PM, Romain Manni-Bucau wrote:
> Why not my proposal of disabling it only for current level (ie same
> node of the tree when coming back)?
>
>
> Romain Manni-Bucau
> @rmannibucau
> http://www.tomitribe.com
> http://rmannibucau.wordpress.com
> https://github.com/rmannibucau
>
> 2016-05-10 17:04 GMT+02:00 Roman Grigoriadi
> <roman.grigoriadi_at_oracle.com <mailto:roman.grigoriadi_at_oracle.com>>:
>
> Yes, number of reentrances in deserializer depends on the model
> tree and is finite. What bothers me is - if we disable reentrant
> calls to deserializers by default, it will fail on the second
> level of recursive model.
>
> On 05/10/2016 04:48 PM, Romain Manni-Bucau wrote:
>> it shouldn't loop since it is not working on the same instance so
>> at some point you will stop (or you have a cycle which is
>> something else but not possible in plain JSON on deserialization
>> - without references I mean).
>>
>>
>>
>> Romain Manni-Bucau
>> @rmannibucau
>> http://www.tomitribe.com
>> http://rmannibucau.wordpress.com
>> https://github.com/rmannibucau
>>
>> 2016-05-10 16:47 GMT+02:00 Roman Grigoriadi
>> <roman.grigoriadi_at_oracle.com <mailto:roman.grigoriadi_at_oracle.com>>:
>>
>> But what if root is a part of deserialized subpart of the tree?
>>
>> class Part {
>> ...
>> List<Subpart>
>> }
>>
>> class Subpart {
>> ...
>> Part child;
>> }
>>
>> now in PartDeserializer you call ctx.deserialize( new
>> TokenImpl<List<Subpart>>() {}.getRuntimeType()) ?
>>
>> On 05/10/2016 04:29 PM, Romain Manni-Bucau wrote:
>>> case I had in mind was when you only deserialize a subpart
>>> of the tree and not the root directly. At each level you can
>>> prevent to re-enter in the same deserializer but you can
>>> need it later in the tree.
>>>
>>>
>>> Romain Manni-Bucau
>>> @rmannibucau
>>> http://www.tomitribe.com
>>> http://rmannibucau.wordpress.com
>>> https://github.com/rmannibucau
>>>
>>> 2016-05-10 16:02 GMT+02:00 Roman Grigoriadi
>>> <roman.grigoriadi_at_oracle.com
>>> <mailto:roman.grigoriadi_at_oracle.com>>:
>>>
>>> Is there a usecase where you actually may need reentrant
>>> deserialize() calls, with recursive models?
>>>
>>> When you call context.deserialize() inside deserializer,
>>> even for other type than deserializer return type, you
>>> may still encounter deserialization into return type of
>>> deserializer inside.
>>>
>>> Roman
>>>
>>>
>>> On 05/10/2016 03:49 PM, Romain Manni-Bucau wrote:
>>>> Hi Roman,
>>>>
>>>> We encountered it in johnzon when Mark implemented it.
>>>> We chose to just prevent these loops since they can
>>>> easily be detected at framework level but not expose it
>>>> to the end user.
>>>>
>>>> typically in your code it would be:
>>>>
>>>> ctx.deserialize(clazz, parser) { // pseudo code
>>>> return this.deserialize(clazz, parser, <ignorePolymorphicDeserializer for root level *only*>);
>>>> }
>>>> Note: in this snippet it would be great to not require the hasNext to be called (ie if called ok but if not then deserialize can do it).
>>>>
>>>>
>>>>
>>>> Romain Manni-Bucau
>>>> @rmannibucau
>>>> http://www.tomitribe.com
>>>> http://rmannibucau.wordpress.com
>>>> https://github.com/rmannibucau
>>>>
>>>> 2016-05-10 15:42 GMT+02:00 Roman Grigoriadi
>>>> <roman.grigoriadi_at_oracle.com
>>>> <mailto:roman.grigoriadi_at_oracle.com>>:
>>>>
>>>> According to polymorphic deserialization, which was
>>>> one of the usecases for deserializers, I
>>>> encountered the fact, that if context.deserialize()
>>>> is called inside the deserializer for the type that
>>>> is the return type for that deserializer, jsonb
>>>> runtime will try to use such deserializer again
>>>> inside. Example:
>>>>
>>>> public class PolymorphicDeserializerimplements JsonbDeserializer<Animal> {
>>>> @Override public Animal deserialize(JsonParser parser, DeserializationContext ctx, Type rtType) {
>>>> Class<?extends Animal> clazz =null;
>>>>
>>>> while (parser.hasNext()) {
>>>> //some code to get class, which will result to
>>>> subclass of an Animal
>>>> //...
>>>> //following will cause adding
>>>> PolymorphicDeserializer instance to call stack
>>>> again, calling deserialize on it
>>>> return ctx.deserialize(clazz, parser);//--- REENTRANT CALL---
>>>> }
>>>> throw new IllegalStateException("animal not found!");
>>>> }
>>>> }
>>>>
>>>> Looks like this is correct behaviour, JSONB runtime
>>>> has deserializer registered for it. Without some
>>>> kind of parameter flag it has no clue not to use
>>>> it. How about adding default to true method
>>>> "boolean isReentrant()" to JsonbDeserializer interface?
>>>>
>>>> Thanks,
>>>> Roman
>>>>
>>>>
>>>
>>>
>>
>>
>
>