google/gson · error · JsonIOException

ReflectionAccessFilter does not permit using reflection for

Error message

ReflectionAccessFilter does not permit using reflection for ${raw} (supertype of ${originalRaw}). Register a TypeAdapter for this type or adjust the access filter.

What it means

Gson walks the full class hierarchy to discover inherited fields. If a ReflectionAccessFilter returns BLOCK_ALL for any supertype (not the immediate type — that is handled separately), Gson refuses to silently drop those inherited fields and throws JsonIOException instead.

Source

Thrown at gson/src/main/java/com/google/gson/internal/bind/ReflectiveTypeAdapterFactory.java:340

    if (raw.isInterface()) {
      return FieldsData.EMPTY;
    }

    Map<String, BoundField> deserializedFields = new LinkedHashMap<>();
    // For serialized fields use a Map to track duplicate field names; otherwise this could be a
    // List<BoundField> instead
    Map<String, BoundField> serializedFields = new LinkedHashMap<>();

    Class<?> originalRaw = raw;
    while (raw != Object.class) {
      Field[] fields = raw.getDeclaredFields();

      // For inherited fields, check if access to their declaring class is allowed
      if (raw != originalRaw && fields.length > 0) {
        FilterResult filterResult =
            ReflectionAccessFilterHelper.getFilterResult(reflectionFilters, raw);
        if (filterResult == FilterResult.BLOCK_ALL) {
          throw new JsonIOException(
              "ReflectionAccessFilter does not permit using reflection for "
                  + raw
                  + " (supertype of "
                  + originalRaw
                  + "). Register a TypeAdapter for this type or adjust the access filter.");
        }
        blockInaccessible = filterResult == FilterResult.BLOCK_INACCESSIBLE;
      }

      for (Field field : fields) {
        boolean serialize = includeField(field, true);
        boolean deserialize = includeField(field, false);
        if (!serialize && !deserialize) {
          continue;
        }
        // The accessor method is only used for records. If the type is a record, we will read out
        // values via its accessor method instead of via reflection. This way we will bypass the
        // accessible restrictions

View on GitHub (pinned to 310ac341f2)

Solutions

  1. Register a custom TypeAdapter for the domain type so Gson never uses reflection for it
  2. Adjust the ReflectionAccessFilter to return ALLOW or BLOCK_INACCESSIBLE instead of BLOCK_ALL for the specific supertype

Example fix

// before
Gson gson = new GsonBuilder()
    .addReflectionAccessFilter(ReflectionAccessFilter.BLOCK_ALL_JAVA)
    .create();
gson.toJson(myType); // throws if MyType extends a java.* class

// after — bypass reflection with a custom adapter
Gson gson = new GsonBuilder()
    .registerTypeAdapter(MyType.class, new MyTypeAdapter())
    .addReflectionAccessFilter(ReflectionAccessFilter.BLOCK_ALL_JAVA)
    .create();
Defensive patterns

Strategy: validation

Validate before calling

// Before serializing, check if any supertype would be blocked by the filter
public static boolean isSupertypeBlocked(Class<?> type, ReflectionAccessFilter filter) {
    Class<?> c = type;
    while (c != Object.class) {
        if (filter.check(c) == FilterResult.BLOCK_ALL) return true;
        c = c.getSuperclass();
    }
    return false;
}

Try / catch

try {
    String json = gson.toJson(obj);
} catch (JsonIOException e) {
    if (e.getMessage().contains("ReflectionAccessFilter does not permit")) {
        // fall back to a manually registered TypeAdapter for this type
    }
}

Prevention

When it happens

Trigger: A domain class extends or implements a type blocked by a ReflectionAccessFilter (e.g., BLOCK_ALL_JAVA or a custom filter blocking java.* or platform types) and Gson needs to serialize or deserialize it reflectively.

Common situations: Security hardening with ReflectionAccessFilter.BLOCK_ALL_PLATFORM on a type that extends a JDK class; JPMS migration where a model class inherits from a blocked package.

Related errors


AI-assisted analysis of google/gson@310ac341f2 (2026-08-10). Data as JSON: /api/errors/57ca6a0613665707. Report an issue: GitHub.