diff --git a/dubbo-rpc/dubbo-rpc-injvm/src/main/java/org/apache/dubbo/rpc/protocol/injvm/DefaultParamDeepCopyUtil.java b/dubbo-rpc/dubbo-rpc-injvm/src/main/java/org/apache/dubbo/rpc/protocol/injvm/DefaultParamDeepCopyUtil.java index 0b6ede8afe..4f5243e655 100644 --- a/dubbo-rpc/dubbo-rpc-injvm/src/main/java/org/apache/dubbo/rpc/protocol/injvm/DefaultParamDeepCopyUtil.java +++ b/dubbo-rpc/dubbo-rpc-injvm/src/main/java/org/apache/dubbo/rpc/protocol/injvm/DefaultParamDeepCopyUtil.java @@ -27,6 +27,7 @@ import org.apache.dubbo.remoting.utils.UrlUtils; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; +import java.lang.reflect.Type; import static org.apache.dubbo.common.constants.LoggerCodeConstants.PROTOCOL_ERROR_DESERIALIZE; @@ -38,7 +39,7 @@ public class DefaultParamDeepCopyUtil implements ParamDeepCopyUtil { @Override @SuppressWarnings({"unchecked"}) - public T copy(URL url, Object src, Class targetClass) { + public T copy(URL url, Object src, Class targetClass, Type type) { Serialization serialization = url.getOrDefaultFrameworkModel() .getExtensionLoader(Serialization.class) .getExtension(UrlUtils.serializationOrDefault(url)); @@ -50,7 +51,11 @@ public class DefaultParamDeepCopyUtil implements ParamDeepCopyUtil { try (ByteArrayInputStream inputStream = new ByteArrayInputStream(outputStream.toByteArray())) { ObjectInput objectInput = serialization.deserialize(url, inputStream); - return objectInput.readObject(targetClass); + if (type != null) { + return objectInput.readObject(targetClass, type); + } else { + return objectInput.readObject(targetClass); + } } catch (ClassNotFoundException | IOException e) { logger.error(PROTOCOL_ERROR_DESERIALIZE, "", "", "Unable to deep copy parameter to target class.", e); } 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 8712d20230..68054d7ddb 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 @@ -152,7 +152,7 @@ public class InjvmInvoker extends AbstractInvoker { appResponse.setObjectAttachments(new HashMap<>(result.getObjectAttachments())); return appResponse; } else { - rebuildValue(invocation, desc, result); + rebuildValue(invocation, invoker, result); AppResponse appResponse = new AppResponse(result.getValue()); appResponse.setObjectAttachments(new HashMap<>(result.getObjectAttachments())); return appResponse; @@ -190,7 +190,7 @@ public class InjvmInvoker extends AbstractInvoker { if (r.hasException()) { rpcResult.setException(r.getException()); } else { - Object rebuildValue = rebuildValue(invocation, desc, r.getValue()); + Object rebuildValue = rebuildValue(invocation, invoker, r.getValue()); rpcResult.setValue(rebuildValue); } } @@ -201,7 +201,7 @@ public class InjvmInvoker extends AbstractInvoker { if (result.hasException()) { rpcResult.setException(result.getException()); } else { - Object rebuildValue = rebuildValue(invocation, desc, result.getValue()); + Object rebuildValue = rebuildValue(invocation, invoker, result.getValue()); rpcResult.setValue(rebuildValue); } rpcResult.setObjectAttachments(new HashMap<>(result.getObjectAttachments())); @@ -232,11 +232,7 @@ public class InjvmInvoker extends AbstractInvoker { } String methodName = invocation.getMethodName(); - ServiceModel consumerServiceModel = invocation.getServiceModel(); - boolean shouldSkip = shouldIgnoreSameModule - && consumerServiceModel != null - && Objects.equals(providerServiceModel.getModuleModel(), consumerServiceModel.getModuleModel()); - if (CommonConstants.$INVOKE.equals(methodName) || shouldSkip) { + if (isSkipCopy(invocation, invoker)) { // generic invoke, skip copy arguments RpcInvocation copiedInvocation = new RpcInvocation( invocation.getTargetServiceUniqueName(), @@ -297,16 +293,43 @@ public class InjvmInvoker extends AbstractInvoker { } } - private Object rebuildValue(Invocation invocation, String desc, Object originValue) { + private boolean isSkipCopy(Invocation invocation, Invoker invoker) { + ServiceModel providerServiceModel = invoker.getUrl().getServiceModel(); + + if (providerServiceModel == null) { + return true; + } + String methodName = invocation.getMethodName(); + + ServiceModel consumerServiceModel = invocation.getServiceModel(); + boolean shouldSkip = shouldIgnoreSameModule + && consumerServiceModel != null + && Objects.equals(providerServiceModel.getModuleModel(), consumerServiceModel.getModuleModel()); + + return CommonConstants.$INVOKE.equals(methodName) + || CommonConstants.$INVOKE_ASYNC.equals(methodName) + || shouldSkip; + } + + private Object rebuildValue(Invocation invocation, Invoker invoker, Object originValue) { + if (isSkipCopy(invocation, invoker)) { + return originValue; + } + Object value = originValue; ClassLoader cl = Thread.currentThread().getContextClassLoader(); try { ServiceModel consumerServiceModel = getUrl().getServiceModel(); if (consumerServiceModel != null) { - Class returnType = getReturnType(consumerServiceModel, invocation.getMethodName(), desc); - if (returnType != null) { - Thread.currentThread().setContextClassLoader(consumerServiceModel.getClassLoader()); - value = paramDeepCopyUtil.copy(consumerUrl, originValue, returnType); + Thread.currentThread().setContextClassLoader(consumerServiceModel.getClassLoader()); + Type[] returnTypes = RpcUtils.getReturnTypes(invocation); + if (returnTypes == null) { + return originValue; + } + if (returnTypes.length == 1) { + value = paramDeepCopyUtil.copy(consumerUrl, originValue, (Class) returnTypes[0]); + } else if (returnTypes.length == 2) { + value = paramDeepCopyUtil.copy(consumerUrl, originValue, (Class) returnTypes[0], returnTypes[1]); } } return value; diff --git a/dubbo-rpc/dubbo-rpc-injvm/src/main/java/org/apache/dubbo/rpc/protocol/injvm/ParamDeepCopyUtil.java b/dubbo-rpc/dubbo-rpc-injvm/src/main/java/org/apache/dubbo/rpc/protocol/injvm/ParamDeepCopyUtil.java index c76a5a16dc..1e76789b91 100644 --- a/dubbo-rpc/dubbo-rpc-injvm/src/main/java/org/apache/dubbo/rpc/protocol/injvm/ParamDeepCopyUtil.java +++ b/dubbo-rpc/dubbo-rpc-injvm/src/main/java/org/apache/dubbo/rpc/protocol/injvm/ParamDeepCopyUtil.java @@ -20,8 +20,14 @@ import org.apache.dubbo.common.URL; import org.apache.dubbo.common.extension.ExtensionScope; import org.apache.dubbo.common.extension.SPI; +import java.lang.reflect.Type; + @SPI(scope = ExtensionScope.FRAMEWORK) public interface ParamDeepCopyUtil { - T copy(URL url, Object src, Class targetClass); + default T copy(URL url, Object src, Class targetClass) { + return copy(url, src, targetClass, null); + } + + T copy(URL url, Object src, Class targetClass, Type type); }