From 2bd1698b2e0dabf5eaaa1ce130bbdd260f28ed04 Mon Sep 17 00:00:00 2001 From: Joao Alves Date: Thu, 28 May 2026 22:35:57 -0300 Subject: [PATCH 1/2] fix: throw clear exception when parameter is not Serializable Previously, passing a non-Serializable parameter to a Dubbo service resulted in a confusing error message. Now a clear IOException with the class name and 'must implement java.io.Serializable' is thrown at encode time in both request and response paths. Fixes #16293 --- .../dubbo/rpc/protocol/dubbo/DubboCodec.java | 27 +++++++++++++++++-- .../rpc/protocol/dubbo/DubboProtocolTest.java | 2 -- 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/DubboCodec.java b/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/DubboCodec.java index 0872ebaaecb6..64d97dc61bd2 100644 --- a/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/DubboCodec.java +++ b/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/DubboCodec.java @@ -294,7 +294,19 @@ protected void encodeRequestData(Channel channel, ObjectOutput out, Object data, Object[] args = inv.getArguments(); if (args != null) { for (int i = 0; i < args.length; i++) { - out.writeObject(callbackServiceCodec.encodeInvocationArgument(channel, inv, i)); + Object arg = callbackServiceCodec.encodeInvocationArgument(channel, inv, i); + try { + out.writeObject(arg); + } catch (IOException e) { + Throwable cause = e.getCause() != null ? e.getCause().getCause() : null; + if (cause instanceof IllegalArgumentException + && cause.getMessage() != null + && cause.getMessage().contains("has not implement Serializable")) { + throw new IOException(arg.getClass().getName() + + " must implement java.io.Serializable", e); + } + throw e; + } } } out.writeAttachments(inv.getObjectAttachments()); @@ -313,7 +325,18 @@ protected void encodeResponseData(Channel channel, ObjectOutput out, Object data out.writeByte(attach ? RESPONSE_NULL_VALUE_WITH_ATTACHMENTS : RESPONSE_NULL_VALUE); } else { out.writeByte(attach ? RESPONSE_VALUE_WITH_ATTACHMENTS : RESPONSE_VALUE); - out.writeObject(ret); + try { + out.writeObject(ret); + } catch (IOException e) { + Throwable cause = e.getCause() != null ? e.getCause().getCause() : null; + if (cause instanceof IllegalArgumentException + && cause.getMessage() != null + && cause.getMessage().contains("has not implement Serializable")) { + throw new IOException(ret.getClass().getName() + + " must implement java.io.Serializable", e); + } + throw e; + } } } else { out.writeByte(attach ? RESPONSE_WITH_EXCEPTION_WITH_ATTACHMENTS : RESPONSE_WITH_EXCEPTION); 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 adfb29a10f77..f7d9fcec5b5d 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 @@ -234,7 +234,6 @@ void testPerm() { } @Test - @Disabled public void testNonSerializedParameter() { DemoService service = new DemoServiceImpl(); int port = NetUtils.getAvailablePort(); @@ -258,7 +257,6 @@ public void testNonSerializedParameter() { } @Test - @Disabled public void testReturnNonSerialized() { DemoService service = new DemoServiceImpl(); int port = NetUtils.getAvailablePort(); From 6605aa2fe66a06c8f718b730b52fd6b37feb5386 Mon Sep 17 00:00:00 2001 From: Joao Alves Date: Thu, 28 May 2026 22:58:55 -0300 Subject: [PATCH 2/2] chore: apply spotless formatting --- .../org/apache/dubbo/rpc/protocol/dubbo/DubboCodec.java | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/DubboCodec.java b/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/DubboCodec.java index 64d97dc61bd2..df5a12a03f14 100644 --- a/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/DubboCodec.java +++ b/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/DubboCodec.java @@ -302,8 +302,7 @@ protected void encodeRequestData(Channel channel, ObjectOutput out, Object data, if (cause instanceof IllegalArgumentException && cause.getMessage() != null && cause.getMessage().contains("has not implement Serializable")) { - throw new IOException(arg.getClass().getName() - + " must implement java.io.Serializable", e); + throw new IOException(arg.getClass().getName() + " must implement java.io.Serializable", e); } throw e; } @@ -332,8 +331,7 @@ protected void encodeResponseData(Channel channel, ObjectOutput out, Object data if (cause instanceof IllegalArgumentException && cause.getMessage() != null && cause.getMessage().contains("has not implement Serializable")) { - throw new IOException(ret.getClass().getName() - + " must implement java.io.Serializable", e); + throw new IOException(ret.getClass().getName() + " must implement java.io.Serializable", e); } throw e; }