google / google/gson

RuntimeTypeAdapterFactory<Base> with JsonDeserializer<Derived> is unsupported

Open
#1,570 4 comments 0 reactions 0 assignees View on GitHub
bug
Dominant language
Java
Stars
24.2k
Forks
4.5k
Avg merge
6d 4h
Merged PRs (30d)
12

Description

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 {
@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 bases;

public static void main(String[] args) {
RuntimeTypeAdapterFactory 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

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.