users@jsonb-spec.java.net

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

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

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
>>>
>>>
>>
>>
>
>