donai41 opened a new issue, #15277: URL: https://github.com/apache/dubbo/issues/15277
### Pre-check - [x] I am sure that all the content I provide is in English. ### Search before asking - [x] I had searched in the [issues](https://github.com/apache/dubbo/issues?q=is%3Aissue) and found no similar issues. ### Apache Dubbo Component Java SDK (apache/dubbo) ### Dubbo Version Dubbo Java 3.3.2 OpenJDK 17 ### Steps to reproduce this issue The current requirement is to implement the broadcast call logic, but each call is expected to be executed asynchronously, the code is as follows: public class ImClusterInvoker<T> extends AbstractClusterInvoker<T> { private Logger logger = LoggerFactory.getLogger(ImClusterInvoker.class); public ImClusterInvoker(Directory<T> directory) { super(directory); } public ImClusterInvoker(Directory<T> directory, URL url) { super(directory, url); } @Override protected Result doInvoke(Invocation invocation, List<Invoker<T>> invokers, LoadBalance loadbalance) throws RpcException { // 检查invokers的状态,如是否为空、是否可用 checkInvokers(invokers, invocation); RpcException exception = null; ThreadPoolExecutor routeExecutor = ThreadPoolManager.getThreadPoolByName("routerExecutor"); CompletableFuture<AppResponse> future = null; for (Invoker<T> invoker : invokers) { try { future = CompletableFuture.supplyAsync(new Supplier<AppResponse>() { @Override public AppResponse get() { RpcContext.getServerContext().setInvoker(invoker); RpcContext.getServerContext().setInvocation(invocation); return (AppResponse) invoker.invoke(invocation); } }, routeExecutor); } catch (RpcException e) { exception = e; logger.warn("Invoker invoke failed", e); } catch (Throwable e) { exception = new RpcException(e.getMessage(), e); logger.warn("Invoker invoke failed", e); } } if (exception != null) { throw exception; } return new AsyncRpcResult(future, invocation); } } The current issue is that the service provider throws an exception when decoding, the exception is as follows: 2025-03-27 00:52:44 WARN ? - [DUBBO] Decode rpc invocation failed: Cannot invoke "Object.hashCode()" because "key" is null, dubbo version: 3.3.2, current host: 192.168.91.1, error code: 4-20. This may be caused by , go to https://dubbo.apache.org/faq/4/20 to find instructions. java.lang.NullPointerException: Cannot invoke "Object.hashCode()" because "key" is null at java.util.concurrent.ConcurrentHashMap.get(ConcurrentHashMap.java:936) ~[?:?] at org.apache.dubbo.rpc.support.GroupServiceKeyCache.getServiceKey(GroupServiceKeyCache.java:37) ~[dubbo-3.3.2.jar:3.3.2] at org.apache.dubbo.rpc.support.ProtocolUtils.serviceKey(ProtocolUtils.java:50) ~[dubbo-3.3.2.jar:3.3.2] at org.apache.dubbo.rpc.protocol.AbstractProtocol.serviceKey(AbstractProtocol.java:85) ~[dubbo-3.3.2.jar:3.3.2] at org.apache.dubbo.rpc.protocol.dubbo.DubboProtocol.getInvoker(DubboProtocol.java:308) ~[dubbo-3.3.2.jar:3.3.2] at org.apache.dubbo.rpc.protocol.dubbo.CallbackServiceCodec.decodeInvocationArgument(CallbackServiceCodec.java:386) ~[dubbo-3.3.2.jar:3.3.2] at org.apache.dubbo.rpc.protocol.dubbo.DecodeableRpcInvocation.decodeArgument(DecodeableRpcInvocation.java:198) ~[dubbo-3.3.2.jar:3.3.2] at org.apache.dubbo.rpc.protocol.dubbo.DecodeableRpcInvocation.decode(DecodeableRpcInvocation.java:183) ~[dubbo-3.3.2.jar:3.3.2] at org.apache.dubbo.rpc.protocol.dubbo.DecodeableRpcInvocation.decode(DecodeableRpcInvocation.java:106) ~[dubbo-3.3.2.jar:3.3.2] at org.apache.dubbo.rpc.protocol.dubbo.DubboCodec.decodeBody(DubboCodec.java:200) ~[dubbo-3.3.2.jar:3.3.2] at org.apache.dubbo.remoting.exchange.codec.ExchangeCodec.decode(ExchangeCodec.java:137) ~[dubbo-3.3.2.jar:3.3.2] at org.apache.dubbo.remoting.exchange.codec.ExchangeCodec.decode(ExchangeCodec.java:92) ~[dubbo-3.3.2.jar:3.3.2] at org.apache.dubbo.rpc.protocol.dubbo.DubboCountCodec.decode(DubboCountCodec.java:59) ~[dubbo-3.3.2.jar:3.3.2] at org.apache.dubbo.remoting.transport.netty4.NettyCodecAdapter$InternalDecoder.decode(NettyCodecAdapter.java:103) ~[dubbo-3.3.2.jar:3.3.2] at io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:529) ~[netty-codec-4.1.87.Final.jar:4.1.87.Final] at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:468) ~[netty-codec-4.1.87.Final.jar:4.1.87.Final] at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:290) ~[netty-codec-4.1.87.Final.jar:4.1.87.Final] at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:444) ~[netty-transport-4.1.87.Final.jar:4.1.87.Final] at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420) ~[netty-transport-4.1.87.Final.jar:4.1.87.Final] at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412) ~[netty-transport-4.1.87.Final.jar:4.1.87.Final] at io.netty.handler.codec.ByteToMessageDecoder.handlerRemoved(ByteToMessageDecoder.java:266) ~[netty-codec-4.1.87.Final.jar:4.1.87.Final] at io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:536) ~[netty-codec-4.1.87.Final.jar:4.1.87.Final] at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:468) ~[netty-codec-4.1.87.Final.jar:4.1.87.Final] at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:290) ~[netty-codec-4.1.87.Final.jar:4.1.87.Final] at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:444) ~[netty-transport-4.1.87.Final.jar:4.1.87.Final] at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420) ~[netty-transport-4.1.87.Final.jar:4.1.87.Final] at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412) ~[netty-transport-4.1.87.Final.jar:4.1.87.Final] at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1410) ~[netty-transport-4.1.87.Final.jar:4.1.87.Final] at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:440) ~[netty-transport-4.1.87.Final.jar:4.1.87.Final] at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420) ~[netty-transport-4.1.87.Final.jar:4.1.87.Final] at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:919) ~[netty-transport-4.1.87.Final.jar:4.1.87.Final] at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:166) ~[netty-transport-4.1.87.Final.jar:4.1.87.Final] at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:788) ~[netty-transport-4.1.87.Final.jar:4.1.87.Final] at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:724) ~[netty-transport-4.1.87.Final.jar:4.1.87.Final] at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:650) ~[netty-transport-4.1.87.Final.jar:4.1.87.Final] at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:562) ~[netty-transport-4.1.87.Final.jar:4.1.87.Final] at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:997) ~[netty-common-4.1.87.Final.jar:4.1.87.Final] at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74) ~[netty-common-4.1.87.Final.jar:4.1.87.Final] at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) ~[netty-common-4.1.87.Final.jar:4.1.87.Final] at java.lang.Thread.run(Thread.java:842) ~[?:?] During debugging, I observed that when invoking the getServiceKey(String serviceName, String serviceVersion, int port) method of the GroupServiceKeyCache class, the first line of the method throws an exception due to serviceName being null, the getServiceKey method is as follows: public String getServiceKey(String serviceName, String serviceVersion, int port) { ConcurrentMap<String, ConcurrentMap<Integer, String>> versionMap = serviceKeyMap.get(serviceName); if (versionMap == null) { serviceKeyMap.putIfAbsent(serviceName, new ConcurrentHashMap<>()); versionMap = serviceKeyMap.get(serviceName); } serviceVersion = serviceVersion == null ? "" : serviceVersion; ConcurrentMap<Integer, String> portMap = versionMap.get(serviceVersion); if (portMap == null) { versionMap.putIfAbsent(serviceVersion, new ConcurrentHashMap<>()); portMap = versionMap.get(serviceVersion); } String serviceKey = portMap.get(port); if (serviceKey == null) { serviceKey = createServiceKey(serviceName, serviceVersion, port); portMap.put(port, serviceKey); } return serviceKey; } I suspect this might be caused by asynchronous calls where RPC Context information fails to propagate properly. However, given my current limited knowledge of Dubbo's internal mechanisms, I'm unable to resolve this issue independently and would appreciate guidance on addressing this problem, Thank you! ### What you expected to happen 感觉应该是上下文信息没设置,希望各位大佬不吝赐教 ### Anything else _No response_ ### Are you willing to submit a pull request to fix on your own? - [ ] Yes I am willing to submit a pull request on my own! ### Code of Conduct - [x] I agree to follow this project's [Code of Conduct](https://www.apache.org/foundation/policies/conduct) -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected] --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
