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]

Reply via email to