Skip to content

RuntimeTypeAdapterFactory<Base> with JsonDeserializer<Derived> is unsupported #1570

@dbirkman-paloalto

Description

@dbirkman-paloalto

Hi,

I want the RuntimeTypeAdapterFactory to differentiate between the derived class types and then deserialize the derived instance using a JsonDeserializer.
However, if I register RuntimeTypeAdapterFactory and JsonDeserializer, Gson does not serialize the derived class using the RuntimeTypeAdapterFactory.

Minimal not working example:

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonParseException;
import com.paloaltonetworks.mag.dms.utils.gson.RuntimeTypeAdapterFactory;

import java.lang.reflect.Type;
import java.util.Arrays;
import java.util.List;

class Base {}
class Derived1 extends Base {}
class Derived2 extends Base {}


class Derived1Deserializer implements JsonDeserializer<Derived1> {
    @Override
    public Derived1 deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
        System.out.println("Can customize deserializing Derived1");
        return null;
    }
}

public class Test {
    private List<Base> bases;

    public static void main(String[] args) {
        RuntimeTypeAdapterFactory<Base> baseRuntimeTypeAdapterFactory = RuntimeTypeAdapterFactory.of(Base.class)
                .registerSubtype(Derived1.class)
                .registerSubtype(Derived2.class);

        GsonBuilder gsonBuilder = new GsonBuilder();
        final Gson gson = gsonBuilder
                .registerTypeAdapter(Derived1.class, new Derived1Deserializer())
                .registerTypeAdapterFactory(baseRuntimeTypeAdapterFactory)
                .create();

        Test test = new Test();
        test.bases = Arrays.asList(new Derived1(), new Derived2());

        String json = gson.toJson(test);
        System.out.println(json); 
        gson.fromJson(json, Test.class);
    }
}

The toJson returns
{"bases":[{},{"type":"Derived2"}]}
instead of:
{"bases":[{"type":"Derived1"},{"type":"Derived2"}]}

and of course fromJson fails afterwards with "JsonParseException: cannot deserialize class Base because it does not define a field named type".

TIA,
Dror

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions