zhouxufu commented on issue #12885:
URL: https://github.com/apache/dubbo/issues/12885#issuecomment-5521551746

   这个问题在较新的版本组合中仍然可以复现,申请重新打开。
   
   ### 环境
   
   - Dubbo:3.3.5
   - Spring Boot:4.1.0(可执行 fat jar)
   - Reactor Core:3.8.6
   - JDK:21
   - 序列化:Hessian2
   
   ### 现象
   
   Dubbo 消费者在 Reactor 的 `boundedElastic` 线程中发起 RPC 调用时,服务端已经正常返回 
DTO,但消费者反序列化阶段出现类似日志:
   
   ```text
   Hessian/Burlap: 'xxx.ResponseDTO' is an unknown class in
   jdk.internal.loader.ClassLoaders$AppClassLoader
   ```
   
   随后 DTO 和枚举被降级反序列化为 `HashMap`,最终发生:
   
   ```text
   ClassCastException: java.util.HashMap cannot be cast to xxx.ResponseDTO
   ```
   
   已经确认:
   
   1. RPC 接口、DTO 和枚举都存在于 Spring Boot 可执行 jar 的嵌套依赖中;
   2. 消费端与提供端使用的 RPC API 版本一致;
   3. 两个服务运行在不同 JVM 中,因此不是同 JVM 类冲突;
   4. 本地 IDE 直接启动正常,打成 Spring Boot fat jar 后在异步线程中复现;
   5. 出错线程的 TCCL 是 `AppClassLoader`,无法加载 Spring Boot fat jar 中由应用 ClassLoader 
管理的 RPC DTO。
   
   ### 临时解决方案
   
   在异步线程真正发起 Dubbo 调用前,将当前线程的 Context ClassLoader 临时切换为 RPC 契约类的 
ClassLoader,并在调用结束后恢复:
   
   ```java
   Thread thread = Thread.currentThread();
   ClassLoader original = thread.getContextClassLoader();
   ClassLoader rpcClassLoader = RpcService.class.getClassLoader();
   try {
       thread.setContextClassLoader(rpcClassLoader);
       return rpcService.invoke(request);
   } finally {
       thread.setContextClassLoader(original);
   }
   ```
   
   应用此处理后,Hessian2 可以正确加载 DTO,返回值不再变成 `HashMap`。
   
   ### 希望确认
   
   Dubbo 3.3.5 中的 `ConsumerClassLoaderFilter` 是否应该覆盖这种 Reactor 
异步线程场景?目前实际反序列化时仍然取到了 `AppClassLoader`。是否可以在 Dubbo/Hessian2 内部优先使用 ServiceModel 
或 RPC 契约所属的 ClassLoader,而不是直接依赖调用线程的 TCCL?
   
   该现象与本 Issue 描述一致,并且在 3.3.5 上仍然存在,麻烦重新打开并继续确认,谢谢。


-- 
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