GSON and InstanceCreator issue

deserialization, gson, java, reflection, type-safety

Solution

Did you look at this? Looks like a nice clean way to implement InstanceCreators.

I was using Gson too, but switched to FlexJSON due to serialization issues. With Flex, you don't need instance creators, just make sure your objects have getters/setters for all fields based on JavaBean spec, and you're good to go:

 ShapeHolder sh = new ShapeHolder();
 sh.addShape(new Rectangle());
 sh.addShape(new Circle());
 JSONSerializer ser = new JSONSerializer();
 String json = ser.deepSerialize(sh);
 JSONDeserializer<ShapeHolder> der = new JSONDeserializer<ShapeHolder>();
 ShapeHolder sh2 = der.deserialize(json);

Problem

I have the following POJOs: ``` public interface Shape { public double calcArea(); public double calcPerimeter(); } public class Rectangle implement Shape { // Various properties of a rectangle } public class Circle implements Shape { // Various properties of a circle } public class ShapeHolder { private List<Shape> shapes; // other stuff } ``` I have no problem getting GSON to serialize an instance of `ShapeHolder` to JSON. But when I try to deserialize a String of that JSON back into a `ShapeHolder` instance, I get errors: ``` String shapeHolderAsStr = getString(); ShapeHolder holder = gson.fromJson(shapeHodlderAsStr, ShapeHolder.class); ``` Throws: ``` Exception in thread "main" java.lang.RuntimeException: Unable to invoke no-args constructor for interface net.myapp.Shape. Register an InstanceCreator with Gson for this type may fix this problem. at com.google.gson.internal.ConstructorConstructor$8.construct(ConstructorConstructor.java:167) at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:162) ... rest of stack trace ommitted for brevity ``` So I looked here and started implementing my own `ShapeInstanceCreator`: ``` public class ShapeInstanceCreator implements InstanceCreator<Shape> { @Override public Shape createInstance(Type type) { // TODO: ??? return null; } } ``` But now I'm stuck: I'm only given a `java.lang.reflect.Type`, but I really need a `java.lang.Object` so I can write code like: ``` public class ShapeInstanceCreator implements InstanceCreator<Shape> { @Override public Shape createInstance(Type type) { Object obj = convertTypeToObject(type); if(obj instanceof Rectangle) { Rectangle r = (Rectangle)obj; return r; } else { Circle c = (Circle)obj; return c; } return null; } } ``` What can I do? Update Per @raffian's suggestion (the link he/she posted), I implemented an `InterfaceAdapter` exactly like the one in the link (I didn't change anything). Now I'm getting the following exception: ``` Exception in thread "main" com.google.gson.JsonParseException: no 'type' member found in what was expected to be an interface wrapper at net.myapp.InterfaceAdapter.get(InterfaceAdapter.java:39) at net.myapp.InterfaceAdapter.deserialize(InterfaceAdapter.java:23) ``` Any ideas?

Original source

Related problems