apache/dubbo · error · RuntimeException

${cause.message}

Error message

${cause.message}

What it means

Thrown while serializing a plain bean by accessor METHOD. For each getter, Dubbo invokes it reflectively and recurses into createDescriptorIfAbsent; any exception (IllegalAccessException, InvocationTargetException from a getter that throws, or a recursion failure) is rewrapped as RuntimeException(cause.message, cause). The original cause is preserved as the exception's cause.

Source

Thrown at dubbo-common/src/main/java/org/apache/dubbo/common/beanutil/JavaBeanSerializeUtil.java:179

            Map map = (Map) obj;
            map.forEach((key, value) -> {
                Object keyDescriptor = key == null ? null : createDescriptorIfAbsent(key, accessor, cache);
                Object valueDescriptor = value == null ? null : createDescriptorIfAbsent(value, accessor, cache);
                descriptor.setProperty(keyDescriptor, valueDescriptor);
            }); // ~ end of loop map
        } else {
            if (JavaBeanAccessor.isAccessByMethod(accessor)) {
                Map<String, Method> methods = ReflectUtils.getBeanPropertyReadMethods(obj.getClass());
                for (Map.Entry<String, Method> entry : methods.entrySet()) {
                    try {
                        Object value = entry.getValue().invoke(obj);
                        if (value == null) {
                            continue;
                        }
                        JavaBeanDescriptor valueDescriptor = createDescriptorIfAbsent(value, accessor, cache);
                        descriptor.setProperty(entry.getKey(), valueDescriptor);
                    } catch (Exception e) {
                        throw new RuntimeException(e.getMessage(), e);
                    }
                } // ~ end of loop method map
            } // ~ end of if (JavaBeanAccessor.isAccessByMethod(accessor))

            if (JavaBeanAccessor.isAccessByField(accessor)) {
                Map<String, Field> fields = ReflectUtils.getBeanPropertyFields(obj.getClass());
                for (Map.Entry<String, Field> entry : fields.entrySet()) {
                    if (!descriptor.containsProperty(entry.getKey())) {
                        try {
                            Object value = entry.getValue().get(obj);
                            if (value == null) {
                                continue;
                            }
                            JavaBeanDescriptor valueDescriptor = createDescriptorIfAbsent(value, accessor, cache);
                            descriptor.setProperty(entry.getKey(), valueDescriptor);
                        } catch (Exception e) {
                            throw new RuntimeException(e.getMessage(), e);
                        }

View on GitHub (pinned to 3a3043227f)

Solutions

  1. Inspect getCause() of the RuntimeException to find the real offending getter (InvocationTargetException target is the user exception).
  2. Fix or guard the getter so it does not throw during serialization.
  3. If a property cannot be serialized, switch to JavaBeanAccessor.FIELD or mark the accessor to skip problematic properties.
  4. Ensure the class and its getters are accessible from Dubbo's classloader/module path.

Example fix

// before
public Expensive getThing() {
    return service.load(); // throws when service is closed
}

// after
public Expensive getThing() {
    return service != null && service.isOpen() ? service.load() : null;
}
Defensive patterns

Strategy: try-catch

Try / catch

try {
    JavaBeanDescriptor d = JavaBeanSerializeUtil.serialize(obj, JavaBeanAccessor.METHOD);
} catch (RuntimeException e) {
    Throwable c = e.getCause(); // InvocationTargetException wraps the real getter fault
    // inspect c to find the offending getter
}

Prevention

When it happens

Trigger: JavaBeanSerializeUtil.serialize(obj, JavaBeanAccessor.METHOD) where a getter throws, is inaccessible, or returns a value whose own serialization fails.

Common situations: A getter performs side-effecting logic that throws (e.g. lazy init hitting a closed resource); a SecurityManager or module boundary blocks reflective access; a self-referential or deeply nested object triggers a downstream error; serializing with METHOD accessor only and a field has no public getter.

Related errors


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