Pre-check
Search before asking
Apache Dubbo Component
Java SDK (apache/dubbo)
Dubbo Version
dubbo 3.2.20 (tag dubbo-3.2.20)
Steps to reproduce this issue
JavaBeanSerializeUtil.serialize() fails on a java.util.HashMap that contains a null key. HashMap permits exactly one null key, so this is a legal argument, and the serializer's own code has an explicit branch for it — but the value that branch produces is then rejected by a null check further down the same call chain.
import org.apache.dubbo.common.beanutil.JavaBeanSerializeUtil;
import java.util.HashMap;
import java.util.Map;
public class NullKeyRepro {
public static void main(String[] args) {
Map<Object, Object> ok = new HashMap<>();
ok.put("k", "v");
System.out.println("without null key: " + (JavaBeanSerializeUtil.serialize(ok) != null));
Map<Object, Object> withNullKey = new HashMap<>();
withNullKey.put(null, "value1"); // HashMap permits one null key
JavaBeanSerializeUtil.serialize(withNullKey); // throws
}
}
What you expected to happen
The map is serialised, with the null key represented as a null descriptor — which is what the code appears to intend.
Anything else
Actual
without null key: true
Exception in thread "main" java.lang.IllegalArgumentException: Property name is null
Root cause
dubbo-common/src/main/java/org/apache/dubbo/common/beanutil/JavaBeanSerializeUtil.java, lines 162–166:
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);
});
Line 163 deliberately produces null for a null key. Line 165 passes it to
JavaBeanDescriptor.setProperty, whose first statement (JavaBeanDescriptor.java,
lines 118–120) is:
public Object setProperty(Object propertyName, Object propertyValue) {
notNull(propertyName, "Property name is null");
return properties.put(propertyName, propertyValue);
}
So the null-producing branch and the null-rejecting guard sit in the same call
chain. Either the ternary on line 163 is dead for keys, or the guard is too strict
for this call site.
Notes
Not introduced by 3.2.20 — the code path is long-standing. The nearest existing
issue I found, #12248, is a different trigger (a null parameter causing an NPE
in generic-call bean mode).
Do you have a (mini) reproduction demo?
Are you willing to submit a pull request to fix on your own?
Code of Conduct
Pre-check
Search before asking
Apache Dubbo Component
Java SDK (apache/dubbo)
Dubbo Version
dubbo 3.2.20 (tag dubbo-3.2.20)
Steps to reproduce this issue
JavaBeanSerializeUtil.serialize() fails on a java.util.HashMap that contains a null key. HashMap permits exactly one null key, so this is a legal argument, and the serializer's own code has an explicit branch for it — but the value that branch produces is then rejected by a null check further down the same call chain.
import org.apache.dubbo.common.beanutil.JavaBeanSerializeUtil;
import java.util.HashMap;
import java.util.Map;
public class NullKeyRepro {
public static void main(String[] args) {
Map<Object, Object> ok = new HashMap<>();
ok.put("k", "v");
System.out.println("without null key: " + (JavaBeanSerializeUtil.serialize(ok) != null));
}
What you expected to happen
The map is serialised, with the null key represented as a null descriptor — which is what the code appears to intend.
Anything else
Actual
Root cause
dubbo-common/src/main/java/org/apache/dubbo/common/beanutil/JavaBeanSerializeUtil.java, lines 162–166:Line 163 deliberately produces
nullfor a null key. Line 165 passes it toJavaBeanDescriptor.setProperty, whose first statement (JavaBeanDescriptor.java,lines 118–120) is:
So the null-producing branch and the null-rejecting guard sit in the same call
chain. Either the ternary on line 163 is dead for keys, or the guard is too strict
for this call site.
Notes
Not introduced by 3.2.20 — the code path is long-standing. The nearest existing
issue I found, #12248, is a different trigger (a null parameter causing an NPE
in generic-call bean mode).
Do you have a (mini) reproduction demo?
Are you willing to submit a pull request to fix on your own?
Code of Conduct