google/gson · error · JsonIOException
Abstract classes can't be instantiated! Adjust the R8 config
Error message
Abstract classes can't be instantiated! Adjust the R8 configuration or register an InstanceCreator or a TypeAdapter for this type. Class name: ${c.getName()}
See ${TroubleshootingGuide.createUrl("r8-abstract-class")} What it means
Thrown when Gson attempts to deserialize into an abstract class and no InstanceCreator or TypeAdapter is registered. The message specifically calls out R8, which on Android can strip a class's default constructor and mark it abstract during optimization. The message includes a troubleshooting guide URL.
Source
Thrown at gson/src/main/java/com/google/gson/internal/ConstructorConstructor.java:424
* ObjectConstructor}, which would then choose another way of creating the object. And it supports
* types which are only serialized but not deserialized (compared to directly throwing an
* exception when the {@code ObjectConstructor} is requested), e.g. when the runtime type of an
* object is inaccessible, but the compile-time type is accessible.
*/
private static final class ThrowingObjectConstructor<T> implements ObjectConstructor<T> {
private final String exceptionMessage;
ThrowingObjectConstructor(String exceptionMessage) {
this.exceptionMessage = exceptionMessage;
}
@Override
public T construct() {
// New exception is created every time to avoid keeping a reference to an exception with
// potentially long stack trace, causing a memory leak
// (which would happen if the exception was already created when the
// `ThrowingObjectConstructor` is created)
throw new JsonIOException(exceptionMessage);
}
}
private static final class InstanceCreatorConstructor<T> implements ObjectConstructor<T> {
private final InstanceCreator<T> instanceCreator;
private final Type type;
InstanceCreatorConstructor(InstanceCreator<T> instanceCreator, Type type) {
this.instanceCreator = instanceCreator;
this.type = type;
}
@Override
public T construct() {
return instanceCreator.createInstance(type);
}
}
}View on GitHub (pinned to 310ac341f2)
Solutions
- Add R8/ProGuard keep rules: -keep class com.example.MyClass { <init>(); }
- Register an InstanceCreator returning a concrete subtype
- Register a custom TypeAdapter for the abstract type
- Deserialize into a concrete subclass instead
Example fix
// before - R8 strips ctor, class becomes abstract
// (no keep rule)
// after - proguard-rules.pro
-keep class com.example.MyModel { <init>(); } Defensive patterns
Strategy: validation
Validate before calling
// Check if target is abstract before deserializing
Class<?> c = (Class<?>) targetType;
if (Modifier.isAbstract(c.getModifiers()) && !c.isArray()) {
throw new IllegalArgumentException(
"Cannot deserialize into abstract class " + c.getName() + "; register InstanceCreator");
} Type guard
static boolean isR8Safe(Class<?> c) {
return !Modifier.isAbstract(c.getModifiers())
&& c.getDeclaredConstructors().length > 0;
} Try / catch
try {
return gson.fromJson(json, MyAbstract.class);
} catch (JsonIOException e) {
if (e.getMessage().startsWith("Abstract classes can't be instantiated")) {
// add R8 keep rule or register InstanceCreator returning a concrete subtype
throw new MyParseException("Abstract class needs InstanceCreator or R8 keep rule", e);
}
throw e;
} Prevention
- Add ProGuard/R8 keep rules for model classes: -keep class com.example.** { <init>(); }
- Register InstanceCreators for abstract types returning concrete subtypes
- Run deserialization tests on the shrunk/minified release build, not just debug
- Deserialize into concrete subtypes instead of abstract bases where possible
When it happens
Trigger: Calling gson.fromJson into an abstract class type without InstanceCreator/TypeAdapter; OR after R8/proguard optimization removed the no-args constructor and marked the class abstract, defeating the no-args-constructor lookup path.
Common situations: Android R8 shrinking removing constructors; deserializing into abstract base types; model classes obfuscated/shrunk without keep rules; migrating to R8 full mode.
Related errors
- Failed to invoke constructor '${ReflectionHelper.constructor
- Cannot allocate ${c}. Usage of JDK sun.misc.Unsafe is enable
- TypeToken must be created with a type argument: new TypeToke
- Unable to create instance of ${rawType}. Registering an Inst
- Interfaces can't be instantiated! Register an InstanceCreato
AI-assisted analysis of google/gson@310ac341f2 (2026-08-10).
Data as JSON: /api/errors/5ed7cb2862bf2cf1.
Report an issue: GitHub.