This is an automated email from the ASF dual-hosted git repository.
zrlw pushed a commit to branch 3.3
in repository https://gitbox.apache.org/repos/asf/dubbo.git
The following commit(s) were added to refs/heads/3.3 by this push:
new 2626e28c16 Fix misleading NPE when request parameter is not
Serializable (#16299)
2626e28c16 is described below
commit 2626e28c16193a099b9cf89e133cd9d55b7d9add
Author: 代码不加冰 <[email protected]>
AuthorDate: Wed Jun 24 17:06:10 2026 +0800
Fix misleading NPE when request parameter is not Serializable (#16299)
* Fix misleading NPE when request parameter is not Serializable
When a Dubbo service is called with non-serializable parameters, the
invocation deserialization fails silently and `path` becomes null. This
null path is then passed to GroupServiceKeyCache which uses a
ConcurrentHashMap that does not accept null keys, resulting in a
confusing NullPointerException.
Added a null check for `path` in DubboProtocol.getInvoker() to throw
a clear RemotingException with a meaningful message pointing users to
the actual cause (non-serializable parameters).
Fixes #16293
Co-Authored-By: Claude Opus 4.7 <[email protected]>
* Make null path error message generic to avoid misleading diagnosis
---------
Co-authored-by: Claude Opus 4.7 <[email protected]>
---
.../apache/dubbo/rpc/protocol/dubbo/DubboProtocol.java | 9 +++++++++
.../dubbo/rpc/protocol/dubbo/DubboProtocolTest.java | 18 ++++++++++++++++++
2 files changed, 27 insertions(+)
diff --git
a/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/DubboProtocol.java
b/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/DubboProtocol.java
index fda55e5667..562367e93a 100644
---
a/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/DubboProtocol.java
+++
b/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/DubboProtocol.java
@@ -290,6 +290,15 @@ public class DubboProtocol extends AbstractProtocol {
boolean isStubServiceInvoke;
int port = channel.getLocalAddress().getPort();
String path = (String) inv.getObjectAttachmentWithoutConvert(PATH_KEY);
+ if (path == null) {
+ throw new RemotingException(
+ channel,
+ "Service path is missing from the invocation, which
indicates the invocation metadata is "
+ + "missing or corrupted. Possible causes include a
request decode failure "
+ + "(e.g. parameter types that failed to
deserialize), an incompatible protocol "
+ + "version, or a custom codec/invocation
implementation that does not set the path, "
+ + "channel: " + channel.getRemoteAddress() + " -->
" + channel.getLocalAddress());
+ }
// if it's stub service on client side(after enable stubevent, usually
is set up onconnect or ondisconnect
// method)
diff --git
a/dubbo-rpc/dubbo-rpc-dubbo/src/test/java/org/apache/dubbo/rpc/protocol/dubbo/DubboProtocolTest.java
b/dubbo-rpc/dubbo-rpc-dubbo/src/test/java/org/apache/dubbo/rpc/protocol/dubbo/DubboProtocolTest.java
index adfb29a10f..4cb386dd54 100644
---
a/dubbo-rpc/dubbo-rpc-dubbo/src/test/java/org/apache/dubbo/rpc/protocol/dubbo/DubboProtocolTest.java
+++
b/dubbo-rpc/dubbo-rpc-dubbo/src/test/java/org/apache/dubbo/rpc/protocol/dubbo/DubboProtocolTest.java
@@ -19,6 +19,8 @@ package org.apache.dubbo.rpc.protocol.dubbo;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.extension.ExtensionLoader;
import org.apache.dubbo.common.utils.NetUtils;
+import org.apache.dubbo.remoting.Channel;
+import org.apache.dubbo.remoting.RemotingException;
import org.apache.dubbo.rpc.Invocation;
import org.apache.dubbo.rpc.Invoker;
import org.apache.dubbo.rpc.Protocol;
@@ -38,6 +40,7 @@ import
org.apache.dubbo.rpc.protocol.dubbo.support.RemoteServiceImpl;
import org.apache.dubbo.rpc.protocol.dubbo.support.Type;
import org.apache.dubbo.rpc.service.EchoService;
+import java.net.InetSocketAddress;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
@@ -281,6 +284,21 @@ class DubboProtocolTest {
}
}
+ @Test
+ void testGetInvokerThrowsOnNullPath() {
+ DubboProtocol dubboProtocol = DubboProtocol.getDubboProtocol();
+ Channel channel = Mockito.mock(Channel.class);
+ InetSocketAddress localAddress = new InetSocketAddress("127.0.0.1",
20880);
+ InetSocketAddress remoteAddress = new InetSocketAddress("127.0.0.1",
12345);
+ Mockito.when(channel.getLocalAddress()).thenReturn(localAddress);
+ Mockito.when(channel.getRemoteAddress()).thenReturn(remoteAddress);
+
+ Invocation inv = Mockito.mock(Invocation.class);
+
Mockito.when(inv.getObjectAttachmentWithoutConvert("path")).thenReturn(null);
+
+ Assertions.assertThrows(RemotingException.class, () ->
dubboProtocol.getInvoker(channel, inv));
+ }
+
@Disabled
@Test
void testRemoteApplicationName() throws Exception {