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)
I've found a solution here.
JUnit tests: