apache/dubbo · error · RuntimeException

Generic serialization

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.

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.

Appendix: 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)