apache/dubbo · error · RuntimeException

Generic serialization [%s] Json syntax exception thrown when

Error message

Generic serialization [%s] Json syntax exception thrown when parsing (object:%s ) error:%s

What it means

Thrown by GsonUtils.toJson(Object) when Gson raises a JsonSyntaxException while serializing the object. Although serialization failures are rarer than parse failures, Gson can throw on non-serializable graphs (e.g. circular references, fields whose types have no adapter, or objects whose toString/adapter throws). Dubbo wraps it in a RuntimeException with a diagnostic including the generic-serialization tag, the object, and Gson's message. The label says 'parsing' but this is the serialization path.

Source

Thrown at dubbo-common/src/main/java/org/apache/dubbo/common/json/GsonUtils.java:72

        }
        Type type = TypeToken.get(originType).getType();
        try {
            return getGson().fromJson(json, type);
        } catch (JsonSyntaxException ex) {
            throw new RuntimeException(String.format(
                    "Generic serialization [%s] Json syntax exception thrown when parsing (message:%s type:%s) error:%s",
                    GENERIC_SERIALIZATION_GSON, json, type.toString(), ex.getMessage()));
        }
    }

    public static String toJson(Object obj) throws RuntimeException {
        if (!isSupportGson()) {
            throw new RuntimeException("Gson is not supported. Please import Gson in JVM env.");
        }
        try {
            return getGson().toJson(obj);
        } catch (JsonSyntaxException ex) {
            throw new RuntimeException(String.format(
                    "Generic serialization [%s] Json syntax exception thrown when parsing (object:%s ) error:%s",
                    GENERIC_SERIALIZATION_GSON, obj, ex.getMessage()));
        }
    }

    private static Gson getGson() {
        if (gsonCache == null || !(gsonCache instanceof Gson)) {
            synchronized (GsonUtils.class) {
                if (gsonCache == null || !(gsonCache instanceof Gson)) {
                    gsonCache = new Gson();
                }
            }
        }
        return (Gson) gsonCache;
    }

    /**
     * @deprecated for uts only

View on GitHub (pinned to 3a3043227f)

Solutions

  1. Inspect the object graph for circular references and break them (transient fields, @JsonAdapter adapters, or DTOs that flatten the cycle).
  2. For non-serializable fields, exclude them with Gson's transient modifier or a custom ExclusionStrategy / TypeAdapter.
  3. Map the runtime object to a JSON-safe DTO before calling toJson.
  4. Catch the RuntimeException at the invocation boundary and convert to a domain-level error.

Example fix

// before
String json = GsonUtils.toJson(entity); // entity has circular parent->child->parent
// after - flatten to a DTO with no back-references
String json = GsonUtils.toJson(EntityDto.from(entity));
Defensive patterns

Strategy: try-catch

Validate before calling

// Detect likely-unsafe graphs before serializing: check for circular references or non-JSON fields.
// Gson has no built-in pre-check; prefer mapping to a JSON-safe DTO instead.

Try / catch

try {
    return GsonUtils.toJson(obj);
} catch (RuntimeException e) {
    // message format: "Generic serialization [gson] Json syntax exception ... (object:%s ) error:%s"
    log.error("gson toJson failed for object {}", obj, e);
    throw new RpcException("Failed to serialize object via gson", e);
}

Prevention

When it happens

Trigger: GsonUtils.toJson(obj) where obj contains a circular reference, a field of a type Gson cannot handle (e.g. a JDK type with no adapter, a Throwable/lambda), a custom serializer that throws, or a value that breaks Gson's reflective field access. toJson is only reached after isSupportGson() passes, so Gson is present.

Common situations: Passing a domain object with bidirectional parent/child links (circular) to a generic call; serializing an object holding non-JSON-friendly JDK types (InputStream, Connection); a field whose getter/field throws during reflection; mixing Gson with a DTO designed for a different serializer (Hessian/Kryo) whose types have no Gson mapping.

Related errors


AI-assisted analysis of apache/dubbo@3a3043227f (2026-08-14). Data as JSON: /api/errors/dde2dec0d57e027d. Report an issue: GitHub.