diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/utils/ClassUtils.java b/dubbo-common/src/main/java/org/apache/dubbo/common/utils/ClassUtils.java index 83c9af30a9..a403519318 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/common/utils/ClassUtils.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/common/utils/ClassUtils.java @@ -113,6 +113,7 @@ public class ClassUtils { PRIMITIVE_WRAPPER_TYPE_MAP.put(Integer.class, int.class); PRIMITIVE_WRAPPER_TYPE_MAP.put(Long.class, long.class); PRIMITIVE_WRAPPER_TYPE_MAP.put(Short.class, short.class); + PRIMITIVE_WRAPPER_TYPE_MAP.put(Void.class, void.class); Set> primitiveTypeNames = new HashSet<>(32); primitiveTypeNames.addAll(PRIMITIVE_WRAPPER_TYPE_MAP.values()); @@ -163,7 +164,7 @@ public class ClassUtils { if (cl == null) { try { cl = Thread.currentThread().getContextClassLoader(); - } catch (Throwable ex) { + } catch (Exception ignored) { // Cannot access thread context ClassLoader - falling back to system class loader... } if (cl == null) { @@ -173,7 +174,7 @@ public class ClassUtils { // getClassLoader() returning null indicates the bootstrap ClassLoader try { cl = ClassLoader.getSystemClassLoader(); - } catch (Throwable ex) { + } catch (Exception ignored) { // Cannot access system ClassLoader - oh well, maybe the caller can live with null... } } @@ -475,7 +476,7 @@ public class ClassUtils { public static boolean isPresent(String className, ClassLoader classLoader) { try { forName(className, classLoader); - } catch (Throwable ignored) { // Ignored + } catch (Exception ignored) { // Ignored return false; } return true; @@ -493,7 +494,7 @@ public class ClassUtils { Class targetClass = null; try { targetClass = forName(className, classLoader); - } catch (Throwable ignored) { // Ignored + } catch (Exception ignored) { // Ignored } return targetClass; } diff --git a/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/ReflectionPackableMethod.java b/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/ReflectionPackableMethod.java index 6f68c53c39..80580b59fb 100644 --- a/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/ReflectionPackableMethod.java +++ b/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/ReflectionPackableMethod.java @@ -17,10 +17,19 @@ package org.apache.dubbo.rpc.protocol.tri; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.lang.reflect.ParameterizedType; +import java.util.Iterator; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + import org.apache.dubbo.common.URL; import org.apache.dubbo.common.constants.CommonConstants; import org.apache.dubbo.common.serialize.MultipleSerialization; import org.apache.dubbo.common.stream.StreamObserver; +import org.apache.dubbo.common.utils.ClassUtils; import org.apache.dubbo.config.Constants; import org.apache.dubbo.remoting.utils.UrlUtils; import org.apache.dubbo.rpc.model.MethodDescriptor; @@ -28,13 +37,6 @@ import org.apache.dubbo.rpc.model.PackableMethod; import com.google.protobuf.Message; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.lang.reflect.ParameterizedType; -import java.util.Iterator; -import java.util.stream.Stream; - import static org.apache.dubbo.common.constants.CommonConstants.$ECHO; import static org.apache.dubbo.common.constants.CommonConstants.PROTOBUF_MESSAGE_CLASS_NAME; import static org.apache.dubbo.rpc.protocol.tri.TripleProtocol.METHOD_ATTR_PACK; @@ -90,8 +92,7 @@ public class ReflectionPackableMethod implements PackableMethod { .getExtension(url.getParameter(Constants.MULTI_SERIALIZATION_KEY, CommonConstants.DEFAULT_KEY)); - this.requestPack = new WrapRequestPack(serialization, url, serializeName, actualRequestTypes, - singleArgument); + this.requestPack = new WrapRequestPack(serialization, url, serializeName, singleArgument); this.responsePack = new WrapResponsePack(serialization, url, actualResponseType); this.requestUnpack = new WrapRequestUnpack(serialization, url, actualRequestTypes); this.responseUnpack = new WrapResponseUnpack(serialization, url, actualResponseType); @@ -320,10 +321,16 @@ public class ReflectionPackableMethod implements PackableMethod { @Override public byte[] pack(Object obj) throws IOException { ByteArrayOutputStream bos = new ByteArrayOutputStream(); - multipleSerialization.serialize(url, serialize, actualResponseType, obj, bos); + Class clz; + if (obj != null) { + clz = obj.getClass(); + } else { + clz = actualResponseType; + } + multipleSerialization.serialize(url, serialize, clz, obj, bos); return TripleCustomerProtocolWapper.TripleResponseWrapper.Builder.newBuilder() .setSerializeType(serialize) - .setType(actualResponseType.getName()) + .setType(clz.getName()) .setData(bos.toByteArray()) .build() .toByteArray(); @@ -332,15 +339,17 @@ public class ReflectionPackableMethod implements PackableMethod { private static class WrapResponseUnpack implements UnPack { + private final Map> classCache = new ConcurrentHashMap<>(); + private final MultipleSerialization serialization; private final URL url; - private final Class returnClass; + private final Class actualResponseType; - private WrapResponseUnpack(MultipleSerialization serialization, URL url, Class returnClass) { + private WrapResponseUnpack(MultipleSerialization serialization, URL url, Class actualResponseType) { this.serialization = serialization; this.url = url; - this.returnClass = returnClass; + this.actualResponseType = actualResponseType; } @Override @@ -349,7 +358,8 @@ public class ReflectionPackableMethod implements PackableMethod { .parseFrom(data); final String serializeType = convertHessianFromWrapper(wrapper.getSerializeType()); ByteArrayInputStream bais = new ByteArrayInputStream(wrapper.getData()); - return serialization.deserialize(url, serializeType, returnClass, bais); + Class clz = getClassFromCache(wrapper.getType(), classCache, actualResponseType); + return serialization.deserialize(url, serializeType, clz, bais); } } @@ -357,21 +367,16 @@ public class ReflectionPackableMethod implements PackableMethod { private final String serialize; private final MultipleSerialization multipleSerialization; - private final String[] argumentsType; private final URL url; private final boolean singleArgument; - private final Class[] actualRequestTypes; private WrapRequestPack(MultipleSerialization multipleSerialization, URL url, String serialize, - Class[] actualRequestTypes, boolean singleArgument) { this.url = url; this.serialize = convertHessianToWrapper(serialize); this.multipleSerialization = multipleSerialization; - this.actualRequestTypes = actualRequestTypes; - this.argumentsType = Stream.of(actualRequestTypes).map(Class::getName).toArray(String[]::new); this.singleArgument = singleArgument; } @@ -385,10 +390,8 @@ public class ReflectionPackableMethod implements PackableMethod { } final TripleCustomerProtocolWapper.TripleRequestWrapper.Builder builder = TripleCustomerProtocolWapper.TripleRequestWrapper.Builder.newBuilder(); builder.setSerializeType(serialize); - for (String type : argumentsType) { - builder.addArgTypes(type); - } for (Object argument : arguments) { + builder.addArgTypes(argument.getClass().getName()); ByteArrayOutputStream bos = new ByteArrayOutputStream(); multipleSerialization.serialize(url, serialize, argument.getClass(), argument, bos); builder.addArgs(bos.toByteArray()); @@ -431,6 +434,8 @@ public class ReflectionPackableMethod implements PackableMethod { private class WrapRequestUnpack implements UnPack { + private final Map> classCache = new ConcurrentHashMap<>(); + private final MultipleSerialization serialization; private final URL url; @@ -451,11 +456,32 @@ public class ReflectionPackableMethod implements PackableMethod { for (int i = 0; i < wrapper.getArgs().size(); i++) { ByteArrayInputStream bais = new ByteArrayInputStream( wrapper.getArgs().get(i)); - ret[i] = serialization.deserialize(url, wrapper.getSerializeType(), - actualRequestTypes[i], - bais); + String className = wrapper.getArgTypes().get(i); + Class clz = getClassFromCache(className, classCache, actualRequestTypes[i]); + ret[i] = serialization.deserialize(url, wrapper.getSerializeType(), clz, bais); } return ret; } + + + } + + + private static Class getClassFromCache(String className, Map> classCache, Class expectedClass) { + if (expectedClass.getName().equals(className)) { + return expectedClass; + } + + Class clz = classCache.get(className); + if (clz == null) { + try { + clz = ClassUtils.forName(className); + } catch (Throwable e) { + // To catch IllegalStateException, LinkageError, ClassNotFoundException + clz = expectedClass; + } + classCache.put(className, clz); + } + return clz; } } diff --git a/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/call/ReflectionAbstractServerCall.java b/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/call/ReflectionAbstractServerCall.java index 200ccf2412..214edbe3ea 100644 --- a/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/call/ReflectionAbstractServerCall.java +++ b/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/call/ReflectionAbstractServerCall.java @@ -46,13 +46,13 @@ public class ReflectionAbstractServerCall extends AbstractServerCall { private List methodDescriptors; public ReflectionAbstractServerCall(Invoker invoker, - ServerStream serverStream, - FrameworkModel frameworkModel, - String acceptEncoding, - String serviceName, - String methodName, - List headerFilters, - Executor executor) { + ServerStream serverStream, + FrameworkModel frameworkModel, + String acceptEncoding, + String serviceName, + String methodName, + List headerFilters, + Executor executor) { super(invoker, serverStream, frameworkModel, getServiceDescriptor(invoker.getUrl()), acceptEncoding, serviceName, methodName, @@ -155,10 +155,8 @@ public class ReflectionAbstractServerCall extends AbstractServerCall { if (isClosed()) { return null; } - if (serviceDescriptor != null) { - ClassLoadUtil.switchContextLoader( - serviceDescriptor.getServiceInterfaceClass().getClassLoader()); - } + ClassLoadUtil.switchContextLoader( + invoker.getUrl().getServiceModel().getClassLoader()); return packableMethod.getRequestUnpack().unpack(data); }