From 4be8594bdefa3b941d062cbcee0794a3718c58b1 Mon Sep 17 00:00:00 2001 From: caoyanan666 <55247691+caoyanan666@users.noreply.github.com> Date: Thu, 20 Jun 2024 09:41:36 +0800 Subject: [PATCH] fix(3.2): injvm invoker throws ClassCastException (#14346) * fix injvm invoker throws ClassCastException * fix unit test * fix unit test * fix NPE --------- Co-authored-by: caoyanan --- .../dubbo/rpc/protocol/injvm/InjvmInvoker.java | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/dubbo-rpc/dubbo-rpc-injvm/src/main/java/org/apache/dubbo/rpc/protocol/injvm/InjvmInvoker.java b/dubbo-rpc/dubbo-rpc-injvm/src/main/java/org/apache/dubbo/rpc/protocol/injvm/InjvmInvoker.java index 68054d7ddb..13e6a0f987 100644 --- a/dubbo-rpc/dubbo-rpc-injvm/src/main/java/org/apache/dubbo/rpc/protocol/injvm/InjvmInvoker.java +++ b/dubbo-rpc/dubbo-rpc-injvm/src/main/java/org/apache/dubbo/rpc/protocol/injvm/InjvmInvoker.java @@ -36,6 +36,7 @@ import org.apache.dubbo.rpc.Result; import org.apache.dubbo.rpc.RpcContext; import org.apache.dubbo.rpc.RpcException; import org.apache.dubbo.rpc.RpcInvocation; +import org.apache.dubbo.rpc.model.ConsumerModel; import org.apache.dubbo.rpc.model.MethodDescriptor; import org.apache.dubbo.rpc.model.ServiceModel; import org.apache.dubbo.rpc.protocol.AbstractInvoker; @@ -317,11 +318,18 @@ public class InjvmInvoker extends AbstractInvoker { } Object value = originValue; - ClassLoader cl = Thread.currentThread().getContextClassLoader(); + ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader(); try { - ServiceModel consumerServiceModel = getUrl().getServiceModel(); - if (consumerServiceModel != null) { - Thread.currentThread().setContextClassLoader(consumerServiceModel.getClassLoader()); + // 1. By default, the classloader of the current Thread is the consumer class loader. + ClassLoader consumerClassLoader = contextClassLoader; + ServiceModel serviceModel = getUrl().getServiceModel(); + // 2. If there is a ConsumerModel in the url, the classloader of the ConsumerModel is consumerLoader + if (Objects.nonNull(serviceModel) && serviceModel instanceof ConsumerModel) { + consumerClassLoader = serviceModel.getClassLoader(); + } + // 3. request result copy + if (Objects.nonNull(consumerClassLoader)) { + Thread.currentThread().setContextClassLoader(consumerClassLoader); Type[] returnTypes = RpcUtils.getReturnTypes(invocation); if (returnTypes == null) { return originValue; @@ -334,7 +342,7 @@ public class InjvmInvoker extends AbstractInvoker { } return value; } finally { - Thread.currentThread().setContextClassLoader(cl); + Thread.currentThread().setContextClassLoader(contextClassLoader); } }