apache/dubbo · error · RuntimeException

Failed to set pojo ${dest.getClass().getSimpleName()} proper

Error message

Failed to set pojo ${dest.getClass().getSimpleName()} property ${name} value ${value.getClass()}, cause: ${e.getMessage()}

What it means

During realization (Map to POJO), PojoUtils finds a setter method for a property, realizes the value to the setter's parameter type, then invokes the setter via method.invoke(dest, value). If the invocation fails (type mismatch after realization, setter throws, access denied), the error is logged via logger.error with the COMMON_REFLECTIVE_OPERATION_FAILED code and then re-thrown as a RuntimeException with a descriptive message including the target class, property name, value class, and cause.

Source

Thrown at dubbo-common/src/main/java/org/apache/dubbo/common/utils/PojoUtils.java:610

                                        value = realize1(
                                                value, (Class<?>) containType, containType, mapGeneric, history);
                                    } else {
                                        Type ptype = method.getGenericParameterTypes()[0];
                                        value = realize1(
                                                value, method.getParameterTypes()[0], ptype, mapGeneric, history);
                                    }
                                } else {
                                    Type ptype = method.getGenericParameterTypes()[0];
                                    value = realize1(value, method.getParameterTypes()[0], ptype, mapGeneric, history);
                                }
                                try {
                                    method.invoke(dest, value);
                                } catch (Exception e) {
                                    String exceptionDescription = "Failed to set pojo "
                                            + dest.getClass().getSimpleName() + " property " + name + " value "
                                            + value.getClass() + ", cause: " + e.getMessage();
                                    logger.error(COMMON_REFLECTIVE_OPERATION_FAILED, "", "", exceptionDescription, e);
                                    throw new RuntimeException(exceptionDescription, e);
                                }
                            } else if (field != null) {
                                value = realize1(value, field.getType(), field.getGenericType(), mapGeneric, history);
                                try {
                                    field.set(dest, value);
                                } catch (IllegalAccessException e) {
                                    throw new RuntimeException(
                                            "Failed to set field " + name + " of pojo "
                                                    + dest.getClass().getName() + " : " + e.getMessage(),
                                            e);
                                }
                            }
                        }
                    }
                }
                return dest;
            }
        }

View on GitHub (pinned to 3a3043227f)

Solutions

  1. Check the exception message — it names the target class, property, and value class — to identify the mismatch.
  2. Align the types in the source Map with the setter's expected parameter type before calling realize.
  3. If the setter has validation logic, ensure the value passes that validation or fix the setter to be more lenient.
  4. Consider using a custom TypeConverter or adjusting the provider DTO's setter to accept the incoming type.

Example fix

// before — setter rejects mismatched type
public void setCount(Integer count) { this.count = count; }
// incoming map: {"count": "five"}
// after — ensure the map uses a compatible value
map.put("count", 5);
// or make the setter lenient
public void setCount(Object val) { this.count = Integer.parseInt(String.valueOf(val)); }
Defensive patterns

Strategy: try-catch

Validate before calling

// Pre-validate setter compatibility before calling realize
for (Method setter : findSetters(dest.getClass())) {
    String propName = getPropertyName(setter);
    if (map.containsKey(propName)) {
        Object val = map.get(propName);
        Class<?> paramType = setter.getParameterTypes()[0];
        if (val != null && !paramType.isAssignableFrom(val.getClass())
                && !canConvert(val.getClass(), paramType)) {
            throw new IllegalArgumentException(
                "Property '" + propName + "': cannot assign " + val.getClass()
                + " to " + paramType);
        }
    }
}
PojoUtils.realize(map, dest.getClass());

Try / catch

try {
    return PojoUtils.realize(map, targetClass);
} catch (RuntimeException e) {
    if (e.getMessage() != null && e.getMessage().startsWith("Failed to set pojo")) {
        logger.error("Property type mismatch during realization", e);
        // Log and rethrow or return partial result
    }
    throw e;
}

Prevention

When it happens

Trigger: Calling PojoUtils.realize(map, targetClass) where the Map contains a value for a property whose setter rejects the realized value — e.g. the setter expects Integer but the Map has a String that can't be converted, or the setter itself throws an IllegalArgumentException due to a business constraint.

Common situations: A generic Dubbo RPC where the consumer sends a field value whose type doesn't cleanly map to the provider's setter parameter type. Common when the provider DTO has strict types or validation in setters, or when the generic map representation uses incompatible types (e.g. BigDecimal vs Double).

Related errors


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