Gson throws UnsupportedOperationException on try to stringify object, which contains java.lang.Class as a field

Viewed 2678

I wrote ClassTypeAdapter, which is correct for classes, but fails when I'm trying to work with objects, which contains classes as fields.

The ClassTypeAdapter with executable main method to reproduce the problem attached.

Any ideas?

    import com.google.gson.Gson;
    import com.google.gson.GsonBuilder;
    import com.google.gson.TypeAdapter;
    import com.google.gson.stream.JsonReader;
    import com.google.gson.stream.JsonWriter;

    import java.io.IOException;

    public class ClassTypeAdapter extends TypeAdapter<Class<?>> {
        private static final String PARAM_NAME = "className";

        @Override
        public void write(JsonWriter out, Class<?> value) throws IOException {
            out.beginObject();

            out.name(PARAM_NAME).value(value.getName());

            out.endObject();
        }

        @Override
        public Class<?> read(JsonReader in) throws IOException {
            Class<?> readClass = null;

            in.beginObject();

            while (in.hasNext()) {
                if (PARAM_NAME.equals(in.nextName())) {
                    try {
                        readClass = Class.forName(in.nextString());
                    } catch (ClassNotFoundException e) {
                        throw new IOException("Class not found", e);
                    }
                }
            }

            in.endObject();

            return readClass;
        }

        public static class TestClass<T> {
            private Class<T> aClass;
        }

        public static void main(String[] args) {
            final Gson gson = new GsonBuilder().registerTypeAdapter(Class.class, new ClassTypeAdapter()).create();

            final TestClass testClass = new TestClass<>();

            System.out.println(gson.toJson(testClass));    // {}
            System.out.println(gson.toJson(Object.class)); // {"className":"java.lang.Object"}

            testClass.aClass = Object.class;

            System.out.println(gson.toJson(testClass));    // UnsupportedOperationException
        }
    }

Stack trace of error:

Exception in thread "main" java.lang.UnsupportedOperationException: Attempted to serialize java.lang.Class: java.lang.Object. Forgot to register a type adapter?
    at com.google.gson.internal.bind.TypeAdapters$1.write(TypeAdapters.java:76)
    at com.google.gson.internal.bind.TypeAdapters$1.write(TypeAdapters.java:69)
    at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:69)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.write(ReflectiveTypeAdapterFactory.java:125)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.write(ReflectiveTypeAdapterFactory.java:243)
    at com.google.gson.Gson.toJson(Gson.java:669)
    at com.google.gson.Gson.toJson(Gson.java:648)
    at com.google.gson.Gson.toJson(Gson.java:603)
    at com.google.gson.Gson.toJson(Gson.java:583)
    at ClassTypeAdapter.main(ClassTypeAdapter.java:56)
1 Answers
Related