1

I wrote a custom (de)serializer so I could serialize my ArrayList of an interface. Here is the serializer:

package com.darkraven.shoppinglist; import com.google.gson.JsonDeserializer; import com.google.gson.JsonElement; import com.google.gson.*; import java.lang.reflect.Type; class InterfaceAdapter<Item> implements JsonSerializer<Item>, JsonDeserializer<Item> { public JsonElement serialize(Item object, Type interfaceType, JsonSerializationContext context) { final JsonObject wrapper = new JsonObject(); wrapper.addProperty("type", object.getClass().getName()); wrapper.add("data", context.serialize(object)); return wrapper; } public Item deserialize(JsonElement elem, Type interfaceType, JsonDeserializationContext context) throws JsonParseException { final JsonObject wrapper = (JsonObject) elem; final JsonElement typeName = get(wrapper, "type"); final JsonElement data = get(wrapper, "data"); final Type actualType = typeForName(typeName); return context.deserialize(data, actualType); } private Type typeForName(final JsonElement typeElem) { try { return Class.forName(typeElem.getAsString()); } catch (ClassNotFoundException e) { throw new JsonParseException(e); } } private JsonElement get(final JsonObject wrapper, String memberName) { final JsonElement elem = wrapper.get(memberName); if (elem == null) throw new JsonParseException("no '" + memberName + "' member found in what was expected to be an interface wrapper"); return elem; } } 

Here is the Item interface, the one to be serialized:

public interface Item extends Parcelable, Serializable{ } 

And here are the two implementations of Item:

public class Category implements Item{ String name; int color; //irrelevant methods } public class Product implements Item{ String name; int color; Category category; //irrelevant methods } 

I get this error on the console:

09-05 10:33:42.613 28602-28602/? W/System.err: at com.darkraven.shoppinglist.InterfaceAdapter.get(InterfaceAdapter.java:34) 09-05 10:33:42.613 28602-28602/? W/System.err: at com.darkraven.shoppinglist.InterfaceAdapter.deserialize(InterfaceAdapter.java:18) 09-05 10:33:42.613 28602-28602/? W/System.err: at com.darkraven.shoppinglist.ShoppingList.readItemArrayList(ShoppingList.java:216) 09-05 10:33:42.613 28602-28602/? W/System.err: at com.darkraven.shoppinglist.ShoppingList.onCreate(ShoppingList.java:37) 

The lines are:

if (elem == null) throw new JsonParseException("no '" + memberName + "' member found in what was expected to be an interface wrapper"); final JsonElement typeName = get(wrapper, "type"); 

What is the problem?

Edit: full stacktrace:

09-05 10:44:45.791 29102-29102/com.darkraven.shoppinglist W/System.err: com.google.gson.JsonParseException: no 'type' member found in what was expected to be an interface wrapper 09-05 10:44:45.791 29102-29102/com.darkraven.shoppinglist W/System.err: at com.darkraven.shoppinglist.InterfaceAdapter.get(InterfaceAdapter.java:35) 09-05 10:44:45.791 29102-29102/com.darkraven.shoppinglist W/System.err: at com.darkraven.shoppinglist.InterfaceAdapter.deserialize(InterfaceAdapter.java:18) 09-05 10:44:45.791 29102-29102/com.darkraven.shoppinglist W/System.err: at com.google.gson.TreeTypeAdapter.read(TreeTypeAdapter.java:58) 09-05 10:44:45.791 29102-29102/com.darkraven.shoppinglist W/System.err: at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.read(TypeAdapterRuntimeTypeWrapper.java:40) 09-05 10:44:45.791 29102-29102/com.darkraven.shoppinglist W/System.err: at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.read(CollectionTypeAdapterFactory.java:81) 09-05 10:44:45.791 29102-29102/com.darkraven.shoppinglist W/System.err: at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.read(CollectionTypeAdapterFactory.java:60) 09-05 10:44:45.791 29102-29102/com.darkraven.shoppinglist W/System.err: at com.google.gson.Gson.fromJson(Gson.java:803) 09-05 10:44:45.791 29102-29102/com.darkraven.shoppinglist W/System.err: at com.google.gson.Gson.fromJson(Gson.java:768) 09-05 10:44:45.791 29102-29102/com.darkraven.shoppinglist W/System.err: at com.darkraven.shoppinglist.ShoppingList.readItemArrayList(ShoppingList.java:216) 09-05 10:44:45.791 29102-29102/com.darkraven.shoppinglist W/System.err: at com.darkraven.shoppinglist.ShoppingList.onCreate(ShoppingList.java:37) 09-05 10:44:45.791 29102-29102/com.darkraven.shoppinglist W/System.err: at android.app.Activity.performCreate(Activity.java:5207) 09-05 10:44:45.791 29102-29102/com.darkraven.shoppinglist W/System.err: at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087) 09-05 10:44:45.791 29102-29102/com.darkraven.shoppinglist W/System.err: at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2195) 09-05 10:44:45.791 29102-29102/com.darkraven.shoppinglist W/System.err: at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2281) 09-05 10:44:45.811 29102-29102/com.darkraven.shoppinglist D/dalvikvm: GC_FOR_ALLOC freed 227K, 3% free 11287K/11536K, paused 19ms, total 19ms 09-05 10:44:45.811 29102-29102/com.darkraven.shoppinglist W/System.err: at android.app.ActivityThread.access$600(ActivityThread.java:148) 09-05 10:44:45.811 29102-29102/com.darkraven.shoppinglist W/System.err: at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1263) 09-05 10:44:45.811 29102-29102/com.darkraven.shoppinglist W/System.err: at android.os.Handler.dispatchMessage(Handler.java:99) 09-05 10:44:45.811 29102-29102/com.darkraven.shoppinglist W/System.err: at android.os.Looper.loop(Looper.java:137) 09-05 10:44:45.811 29102-29102/com.darkraven.shoppinglist W/System.err: at android.app.ActivityThread.main(ActivityThread.java:5124) 09-05 10:44:45.811 29102-29102/com.darkraven.shoppinglist W/System.err: at java.lang.reflect.Method.invokeNative(Native Method) 09-05 10:44:45.811 29102-29102/com.darkraven.shoppinglist W/System.err: at java.lang.reflect.Method.invoke(Method.java:525) 09-05 10:44:45.811 29102-29102/com.darkraven.shoppinglist W/System.err: at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737) 09-05 10:44:45.811 29102-29102/com.darkraven.shoppinglist W/System.err: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553) 09-05 10:44:45.811 29102-29102/com.darkraven.shoppinglist W/System.err: at dalvik.system.NativeStart.main(Native Method) 09-05 10:44:45.821 29102-29102/com.darkraven.shoppinglist W/System.err: com.google.gson.JsonParseException: no 'data' member found in what was expected to be an interface wrapper 09-05 10:44:45.821 29102-29102/com.darkraven.shoppinglist W/System.err: at com.darkraven.shoppinglist.InterfaceAdapter.get(InterfaceAdapter.java:35) 09-05 10:44:45.821 29102-29102/com.darkraven.shoppinglist W/System.err: at com.darkraven.shoppinglist.InterfaceAdapter.deserialize(InterfaceAdapter.java:19) 09-05 10:44:45.821 29102-29102/com.darkraven.shoppinglist W/System.err: at com.google.gson.TreeTypeAdapter.read(TreeTypeAdapter.java:58) 09-05 10:44:45.821 29102-29102/com.darkraven.shoppinglist W/System.err: at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.read(TypeAdapterRuntimeTypeWrapper.java:40) 09-05 10:44:45.821 29102-29102/com.darkraven.shoppinglist W/System.err: at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.read(CollectionTypeAdapterFactory.java:81) 09-05 10:44:45.821 29102-29102/com.darkraven.shoppinglist W/System.err: at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.read(CollectionTypeAdapterFactory.java:60) 09-05 10:44:45.821 29102-29102/com.darkraven.shoppinglist W/System.err: at com.google.gson.Gson.fromJson(Gson.java:803) 09-05 10:44:45.821 29102-29102/com.darkraven.shoppinglist W/System.err: at com.google.gson.Gson.fromJson(Gson.java:768) 09-05 10:44:45.821 29102-29102/com.darkraven.shoppinglist W/System.err: at com.darkraven.shoppinglist.ShoppingList.readItemArrayList(ShoppingList.java:216) 09-05 10:44:45.821 29102-29102/com.darkraven.shoppinglist W/System.err: at com.darkraven.shoppinglist.ShoppingList.onCreate(ShoppingList.java:37) 09-05 10:44:45.821 29102-29102/com.darkraven.shoppinglist W/System.err: at android.app.Activity.performCreate(Activity.java:5207) 09-05 10:44:45.821 29102-29102/com.darkraven.shoppinglist W/System.err: at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087) 09-05 10:44:45.821 29102-29102/com.darkraven.shoppinglist W/System.err: at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2195) 09-05 10:44:45.821 29102-29102/com.darkraven.shoppinglist W/System.err: at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2281) 09-05 10:44:45.821 29102-29102/com.darkraven.shoppinglist W/System.err: at android.app.ActivityThread.access$600(ActivityThread.java:148) 09-05 10:44:45.821 29102-29102/com.darkraven.shoppinglist W/System.err: at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1263) 09-05 10:44:45.821 29102-29102/com.darkraven.shoppinglist W/System.err: at android.os.Handler.dispatchMessage(Handler.java:99) 09-05 10:44:45.821 29102-29102/com.darkraven.shoppinglist W/System.err: at android.os.Looper.loop(Looper.java:137) 09-05 10:44:45.821 29102-29102/com.darkraven.shoppinglist W/System.err: at android.app.ActivityThread.main(ActivityThread.java:5124) 09-05 10:44:45.821 29102-29102/com.darkraven.shoppinglist W/System.err: at java.lang.reflect.Method.invokeNative(Native Method) 09-05 10:44:45.821 29102-29102/com.darkraven.shoppinglist W/System.err: at java.lang.reflect.Method.invoke(Method.java:525) 09-05 10:44:45.821 29102-29102/com.darkraven.shoppinglist W/System.err: at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737) 09-05 10:44:45.821 29102-29102/com.darkraven.shoppinglist W/System.err: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553) 09-05 10:44:45.821 29102-29102/com.darkraven.shoppinglist W/System.err: at dalvik.system.NativeStart.main(Native Method) 09-05 10:44:45.821 29102-29102/com.darkraven.shoppinglist W/System.err: java.lang.NullPointerException 09-05 10:44:45.821 29102-29102/com.darkraven.shoppinglist W/System.err: at com.darkraven.shoppinglist.InterfaceAdapter.typeForName(InterfaceAdapter.java:26) 09-05 10:44:45.821 29102-29102/com.darkraven.shoppinglist W/System.err: at com.darkraven.shoppinglist.InterfaceAdapter.deserialize(InterfaceAdapter.java:20) 09-05 10:44:45.821 29102-29102/com.darkraven.shoppinglist W/System.err: at com.google.gson.TreeTypeAdapter.read(TreeTypeAdapter.java:58) 09-05 10:44:45.821 29102-29102/com.darkraven.shoppinglist W/System.err: at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.read(TypeAdapterRuntimeTypeWrapper.java:40) 09-05 10:44:45.821 29102-29102/com.darkraven.shoppinglist W/System.err: at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.read(CollectionTypeAdapterFactory.java:81) 09-05 10:44:45.821 29102-29102/com.darkraven.shoppinglist W/System.err: at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.read(CollectionTypeAdapterFactory.java:60) 09-05 10:44:45.821 29102-29102/com.darkraven.shoppinglist W/System.err: at com.google.gson.Gson.fromJson(Gson.java:803) 09-05 10:44:45.821 29102-29102/com.darkraven.shoppinglist W/System.err: at com.google.gson.Gson.fromJson(Gson.java:768) 09-05 10:44:45.821 29102-29102/com.darkraven.shoppinglist W/System.err: at com.darkraven.shoppinglist.ShoppingList.readItemArrayList(ShoppingList.java:216) 09-05 10:44:45.821 29102-29102/com.darkraven.shoppinglist W/System.err: at com.darkraven.shoppinglist.ShoppingList.onCreate(ShoppingList.java:37) 09-05 10:44:45.821 29102-29102/com.darkraven.shoppinglist W/System.err: at android.app.Activity.performCreate(Activity.java:5207) 09-05 10:44:45.821 29102-29102/com.darkraven.shoppinglist W/System.err: at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087) 09-05 10:44:45.821 29102-29102/com.darkraven.shoppinglist W/System.err: at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2195) 09-05 10:44:45.821 29102-29102/com.darkraven.shoppinglist W/System.err: at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2281) 09-05 10:44:45.821 29102-29102/com.darkraven.shoppinglist W/System.err: at android.app.ActivityThread.access$600(ActivityThread.java:148) 09-05 10:44:45.821 29102-29102/com.darkraven.shoppinglist W/System.err: at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1263) 09-05 10:44:45.821 29102-29102/com.darkraven.shoppinglist W/System.err: at android.os.Handler.dispatchMessage(Handler.java:99) 09-05 10:44:45.821 29102-29102/com.darkraven.shoppinglist W/System.err: at android.os.Looper.loop(Looper.java:137) 09-05 10:44:45.821 29102-29102/com.darkraven.shoppinglist W/System.err: at android.app.ActivityThread.main(ActivityThread.java:5124) 09-05 10:44:45.821 29102-29102/com.darkraven.shoppinglist W/System.err: at java.lang.reflect.Method.invokeNative(Native Method) 09-05 10:44:45.821 29102-29102/com.darkraven.shoppinglist W/System.err: at java.lang.reflect.Method.invoke(Method.java:525) 09-05 10:44:45.821 29102-29102/com.darkraven.shoppinglist W/System.err: at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737) 09-05 10:44:45.821 29102-29102/com.darkraven.shoppinglist W/System.err: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553) 09-05 10:44:45.821 29102-29102/com.darkraven.shoppinglist W/System.err: at dalvik.system.NativeStart.main(Native Method) 

Edit: writing method:

public void writeItemArrayList(){ try{ File file = new File(this.getFilesDir(), "shoppinglist.json"); Gson gson = new GsonBuilder().registerTypeAdapter(Item.class, new InterfaceAdapter<Item>()) .create(); FileWriter writer = new FileWriter(file); writer.write(gson.toJson(items)); writer.flush(); writer.close(); }catch (Exception e){ } } 

Reading method:

public void readItemArrayList(){ try{ FileReader reader = new FileReader(new File(this.getFilesDir(), "shoppinglist.json")); Gson gson = new GsonBuilder().registerTypeAdapter(Item.class, new InterfaceAdapter<Item>()) .create(); this.items = gson.fromJson(reader, new TypeToken<ArrayList<Item>>(){}.getType()); reader.close(); }catch(Exception e){ e.printStackTrace(); } } 
5
  • 2
    Can you add the full stack trace, the exception isnt listed on the current output. Commented Sep 5, 2013 at 8:41
  • Added, sorry, that was all that showed before. Commented Sep 5, 2013 at 8:46
  • Have you tried printing out the json object as a string to make sure it has the "type" object? Can you post the json object as a string at the beginning of the deserialize method? And finally try making sure that object.getClass().getName() isnt returning null, if so it is likely that it is making the "type" variable not appear. Commented Sep 5, 2013 at 8:55
  • Doesn`t seem to be writing it with the serializer, that might be the issue. I'll edit the OP and post the method. Commented Sep 5, 2013 at 9:01
  • @ns47731 added the methods. Commented Sep 5, 2013 at 9:35

1 Answer 1

2

Look at GSON not calling my TypeAdapter for a type which is an interface

I got your code working with by using registerTypeHierarchyAdapter noted from the link , I posted all of it because I had to make a change in your serialize method so I didn't get a stack overflow exception.

public void writeItemArrayList(){ try{ File file = new File(this.getFilesDir(), "shoppinglist.json"); /*change here*/Gson gson = new GsonBuilder().registerTypeHierarchyAdapter(Item.class, new InterfaceAdapter<Item>()) .create(); FileWriter writer = new FileWriter(file); writer.write(gson.toJson(items)); writer.flush(); writer.close(); }catch (Exception e){ } } public void readItemArrayList(){ try{ FileReader reader = new FileReader(new File(this.getFilesDir(), "shoppinglist.json")); Gson gson = new GsonBuilder().registerTypeAdapter(Item.class, new InterfaceAdapter<Item>()) .create(); this.items = gson.fromJson(reader, new TypeToken<ArrayList<Item>>(){}.getType()); reader.close(); } catch(Exception e){ e.printStackTrace(); } } class InterfaceAdapter<Item> implements JsonSerializer<Item>, JsonDeserializer<Item> { public JsonElement serialize(Item object, Type interfaceType, JsonSerializationContext context) { final JsonObject wrapper = new JsonObject(); System.out.println("serialize " + object); wrapper.addProperty("type", object.getClass().getName()); /*change here*/Gson gson = new Gson(); /*change here*/wrapper.add("data", gson.toJsonTree(object, interfaceType)); return wrapper; } ....... same code as before below ....... } 
Sign up to request clarification or add additional context in comments.

1 Comment

I get com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 2