users@jsonb-spec.java.net

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

From: Roman Grigoriadi <roman.grigoriadi_at_oracle.com>
Date: Tue, 10 May 2016 16:02:18 +0200

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