From f9383cec9220bd2182d6568d2568d06d93708418 Mon Sep 17 00:00:00 2001 From: Orez Date: Fri, 17 Jun 2022 15:40:51 +0800 Subject: [PATCH 1/6] fix triple class loader problem --- .../rpc/server/triple/GenericServiceImpl.java | 26 +++++++++++------- .../sofa/rpc/server/triple/TripleServer.java | 13 ++++++++- .../server/triple/GenericServiceImplTest.java | 11 +++++--- .../sofa/rpc/test/triple/SampleService.java | 27 +++++++++++++++++++ .../rpc/test/triple/TripleServerTest.java | 6 ----- 5 files changed, 63 insertions(+), 20 deletions(-) create mode 100644 test/test-integration/src/test/java/com/alipay/sofa/rpc/test/triple/SampleService.java diff --git a/remoting/remoting-triple/src/main/java/com/alipay/sofa/rpc/server/triple/GenericServiceImpl.java b/remoting/remoting-triple/src/main/java/com/alipay/sofa/rpc/server/triple/GenericServiceImpl.java index 30a283b64..52b22ff3c 100644 --- a/remoting/remoting-triple/src/main/java/com/alipay/sofa/rpc/server/triple/GenericServiceImpl.java +++ b/remoting/remoting-triple/src/main/java/com/alipay/sofa/rpc/server/triple/GenericServiceImpl.java @@ -21,6 +21,7 @@ import com.alipay.sofa.rpc.common.cache.ReflectCache; import com.alipay.sofa.rpc.common.utils.ClassTypeUtils; import com.alipay.sofa.rpc.common.utils.ClassUtils; +import com.alipay.sofa.rpc.config.ConfigUniqueNameGenerator; import com.alipay.sofa.rpc.config.ProviderConfig; import com.alipay.sofa.rpc.core.exception.RpcErrorType; import com.alipay.sofa.rpc.core.exception.SofaRpcException; @@ -30,7 +31,6 @@ import com.alipay.sofa.rpc.invoke.Invoker; import com.alipay.sofa.rpc.log.Logger; import com.alipay.sofa.rpc.log.LoggerFactory; -import com.alipay.sofa.rpc.message.MessageBuilder; import com.alipay.sofa.rpc.tracer.sofatracer.TracingContextKey; import com.alipay.sofa.rpc.transport.ByteArrayWrapperByteBuf; import com.google.protobuf.ByteString; @@ -53,31 +53,37 @@ public class GenericServiceImpl extends SofaGenericServiceTriple.GenericServiceI private static final Logger LOGGER = LoggerFactory.getLogger(GenericServiceImpl.class); protected Invoker invoker; - protected Class proxyClass; + protected ProviderConfig providerConfig; - public GenericServiceImpl(Invoker invoker, Class proxyClass) { + public GenericServiceImpl(Invoker invoker, ProviderConfig proxyClass) { super(); this.invoker = invoker; - this.proxyClass = proxyClass; // todo use reflect to get Class + this.providerConfig = proxyClass; // todo use reflect to get Class + String key = ConfigUniqueNameGenerator.getUniqueName(providerConfig); + ReflectCache.registerServiceClassLoader(key, providerConfig.getProxyClass().getClassLoader()); + // 缓存接口的方法 + for (Method m : providerConfig.getProxyClass().getMethods()) { + ReflectCache.putOverloadMethodCache(key, m); + } } @Override public void generic(Request request, StreamObserver responseObserver) { - SofaRequest sofaRequest = TracingContextKey.getKeySofaRequest().get(Context.current()); + ClassLoader oldClassLoader = Thread.currentThread().getContextClassLoader(); + SofaRequest sofaRequest = TracingContextKey.getKeySofaRequest().get(Context.current()); String methodName = sofaRequest.getMethodName(); - String interfaceName = sofaRequest.getInterfaceName(); - ClassLoader oldClassLoader = Thread.currentThread().getContextClassLoader(); try { - Class proxyClass = ClassTypeUtils.getClass(interfaceName); - ClassLoader interfaceClassLoader = proxyClass.getClassLoader(); + String key = ConfigUniqueNameGenerator.getUniqueName(providerConfig); + ClassLoader interfaceClassLoader = ReflectCache.getServiceClassLoader(key); Thread.currentThread().setContextClassLoader(interfaceClassLoader); Class[] argTypes = getArgTypes(request); Serializer serializer = SerializerFactory.getSerializer(request.getSerializeType()); - Method declaredMethod = proxyClass.getDeclaredMethod(methodName, argTypes); + Method declaredMethod = ReflectCache.getOverloadMethodCache(key, methodName, request.getArgTypesList() + .toArray(new String[0])); Object[] invokeArgs = getInvokeArgs(request, argTypes, serializer); // fill sofaRequest diff --git a/remoting/remoting-triple/src/main/java/com/alipay/sofa/rpc/server/triple/TripleServer.java b/remoting/remoting-triple/src/main/java/com/alipay/sofa/rpc/server/triple/TripleServer.java index 6046912f4..6d3dcbf14 100644 --- a/remoting/remoting-triple/src/main/java/com/alipay/sofa/rpc/server/triple/TripleServer.java +++ b/remoting/remoting-triple/src/main/java/com/alipay/sofa/rpc/server/triple/TripleServer.java @@ -16,7 +16,9 @@ */ package com.alipay.sofa.rpc.server.triple; +import com.alipay.sofa.rpc.common.cache.ReflectCache; import com.alipay.sofa.rpc.common.struct.NamedThreadFactory; +import com.alipay.sofa.rpc.config.ConfigUniqueNameGenerator; import com.alipay.sofa.rpc.config.ProviderConfig; import com.alipay.sofa.rpc.config.ServerConfig; import com.alipay.sofa.rpc.core.exception.SofaRpcRuntimeException; @@ -267,7 +269,7 @@ public void registerProcessor(ProviderConfig providerConfig, Invoker instance) { BindableService bindableService = (BindableService) providerConfig.getRef(); serviceDef = bindableService.bindService(); } else { - GenericServiceImpl genericService = new GenericServiceImpl(uniqueIdInvoker, providerConfig.getProxyClass()); + GenericServiceImpl genericService = new GenericServiceImpl(uniqueIdInvoker, providerConfig); genericService.setProxiedImpl(genericService); serviceDef = buildSofaServiceDef(genericService, providerConfig); } @@ -380,6 +382,7 @@ protected List buildInterceptorChain(ServerServiceDefin @Override public void unRegisterProcessor(ProviderConfig providerConfig, boolean closeIfNoEntry) { this.lock.lock(); + cleanReflectCache(providerConfig); try { ServerServiceDefinition serverServiceDefinition = this.serviceInfo.get(providerConfig); UniqueIdInvoker uniqueIdInvoker = this.invokerMap.get(providerConfig.getInterfaceId()); @@ -403,6 +406,14 @@ public void unRegisterProcessor(ProviderConfig providerConfig, boolean closeIfNo } } + public void cleanReflectCache(ProviderConfig providerConfig) { + String key = ConfigUniqueNameGenerator.getUniqueName(providerConfig); + ReflectCache.unRegisterServiceClassLoader(key); + ReflectCache.invalidateMethodCache(key); + ReflectCache.invalidateMethodSigsCache(key); + ReflectCache.invalidateOverloadMethodCache(key); + } + @Override public void destroy() { stop(); diff --git a/remoting/remoting-triple/src/test/java/com/alipay/sofa/rpc/server/triple/GenericServiceImplTest.java b/remoting/remoting-triple/src/test/java/com/alipay/sofa/rpc/server/triple/GenericServiceImplTest.java index dda7674aa..b5b1b046c 100644 --- a/remoting/remoting-triple/src/test/java/com/alipay/sofa/rpc/server/triple/GenericServiceImplTest.java +++ b/remoting/remoting-triple/src/test/java/com/alipay/sofa/rpc/server/triple/GenericServiceImplTest.java @@ -19,6 +19,7 @@ import com.alipay.sofa.rpc.codec.Serializer; import com.alipay.sofa.rpc.codec.SerializerFactory; import com.alipay.sofa.rpc.codec.sofahessian.SofaHessianSerializer; +import com.alipay.sofa.rpc.config.ConfigUniqueNameGenerator; import com.alipay.sofa.rpc.config.ProviderConfig; import com.alipay.sofa.rpc.core.request.SofaRequest; import com.alipay.sofa.rpc.filter.ProviderInvoker; @@ -46,18 +47,22 @@ public class GenericServiceImplTest { private GenericServiceImpl genericService; private MockStreamObserver responseObserver; + private ProviderConfig providerConfig; + public GenericServiceImplTest(){ - ProviderConfig providerConfig = new ProviderConfig<>(); + providerConfig = new ProviderConfig<>(); providerConfig.setRef(new HelloServiceImpl()); - providerConfig.setProxyClass(HelloService.class); + providerConfig.setInterfaceId(HelloService.class.getName()); ProviderInvoker invoker = new ProviderInvoker<>(providerConfig); - genericService = new GenericServiceImpl(invoker,providerConfig.getProxyClass()); + genericService = new GenericServiceImpl(invoker,providerConfig); responseObserver = new MockStreamObserver<>(); } @Test public void testPrimitiveType() throws NoSuchMethodException { // test return primitive type + Assert.assertEquals("com.alipay.sofa.rpc.server.triple.HelloService:1.0", + ConfigUniqueNameGenerator.getUniqueName(providerConfig)); String methodName = "testPrimitiveType"; Method method = HelloService.class.getDeclaredMethod(methodName, long.class); diff --git a/test/test-integration/src/test/java/com/alipay/sofa/rpc/test/triple/SampleService.java b/test/test-integration/src/test/java/com/alipay/sofa/rpc/test/triple/SampleService.java new file mode 100644 index 000000000..69982a471 --- /dev/null +++ b/test/test-integration/src/test/java/com/alipay/sofa/rpc/test/triple/SampleService.java @@ -0,0 +1,27 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alipay.sofa.rpc.test.triple; + +/** + * @author zhaowang + * @version : SampleService.java, v 0.1 2022年06月17日 3:33 PM zhaowang + */ +public interface SampleService { + + String hello(String name); + +} diff --git a/test/test-integration/src/test/java/com/alipay/sofa/rpc/test/triple/TripleServerTest.java b/test/test-integration/src/test/java/com/alipay/sofa/rpc/test/triple/TripleServerTest.java index 6870dae2b..93bb26758 100644 --- a/test/test-integration/src/test/java/com/alipay/sofa/rpc/test/triple/TripleServerTest.java +++ b/test/test-integration/src/test/java/com/alipay/sofa/rpc/test/triple/TripleServerTest.java @@ -242,12 +242,6 @@ public void testSyncTimeout() { Assert.assertTrue(exp); } - public interface SampleService { - - String hello(String name); - - } - @BeforeClass public static void adBeforeClass() { RpcRunningState.setUnitTestMode(true); From 9fa9413dd4dc5d3ab15365f4c0f0ad9788b9554d Mon Sep 17 00:00:00 2001 From: Orez Date: Fri, 17 Jun 2022 15:44:48 +0800 Subject: [PATCH 2/6] modify parameter name --- .../com/alipay/sofa/rpc/server/triple/GenericServiceImpl.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/remoting/remoting-triple/src/main/java/com/alipay/sofa/rpc/server/triple/GenericServiceImpl.java b/remoting/remoting-triple/src/main/java/com/alipay/sofa/rpc/server/triple/GenericServiceImpl.java index 52b22ff3c..d5ad543c1 100644 --- a/remoting/remoting-triple/src/main/java/com/alipay/sofa/rpc/server/triple/GenericServiceImpl.java +++ b/remoting/remoting-triple/src/main/java/com/alipay/sofa/rpc/server/triple/GenericServiceImpl.java @@ -55,10 +55,10 @@ public class GenericServiceImpl extends SofaGenericServiceTriple.GenericServiceI protected Invoker invoker; protected ProviderConfig providerConfig; - public GenericServiceImpl(Invoker invoker, ProviderConfig proxyClass) { + public GenericServiceImpl(Invoker invoker, ProviderConfig providerConfig) { super(); this.invoker = invoker; - this.providerConfig = proxyClass; // todo use reflect to get Class + this.providerConfig = providerConfig; // todo use reflect to get Class String key = ConfigUniqueNameGenerator.getUniqueName(providerConfig); ReflectCache.registerServiceClassLoader(key, providerConfig.getProxyClass().getClassLoader()); // 缓存接口的方法 From e37cb8521412992b95b44dbeaecbd428fca46438 Mon Sep 17 00:00:00 2001 From: Orez Date: Fri, 17 Jun 2022 15:46:54 +0800 Subject: [PATCH 3/6] remove todo --- .../com/alipay/sofa/rpc/server/triple/GenericServiceImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/remoting/remoting-triple/src/main/java/com/alipay/sofa/rpc/server/triple/GenericServiceImpl.java b/remoting/remoting-triple/src/main/java/com/alipay/sofa/rpc/server/triple/GenericServiceImpl.java index d5ad543c1..05dfd3708 100644 --- a/remoting/remoting-triple/src/main/java/com/alipay/sofa/rpc/server/triple/GenericServiceImpl.java +++ b/remoting/remoting-triple/src/main/java/com/alipay/sofa/rpc/server/triple/GenericServiceImpl.java @@ -58,7 +58,7 @@ public class GenericServiceImpl extends SofaGenericServiceTriple.GenericServiceI public GenericServiceImpl(Invoker invoker, ProviderConfig providerConfig) { super(); this.invoker = invoker; - this.providerConfig = providerConfig; // todo use reflect to get Class + this.providerConfig = providerConfig; String key = ConfigUniqueNameGenerator.getUniqueName(providerConfig); ReflectCache.registerServiceClassLoader(key, providerConfig.getProxyClass().getClassLoader()); // 缓存接口的方法 From 67bf6f8820ae5a7ce4e633f6ce0ec8d2c889bc91 Mon Sep 17 00:00:00 2001 From: Orez Date: Wed, 22 Jun 2022 11:57:51 +0800 Subject: [PATCH 4/6] remove unused cache --- .../com/alipay/sofa/rpc/server/triple/GenericServiceImpl.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/remoting/remoting-triple/src/main/java/com/alipay/sofa/rpc/server/triple/GenericServiceImpl.java b/remoting/remoting-triple/src/main/java/com/alipay/sofa/rpc/server/triple/GenericServiceImpl.java index 05dfd3708..00c06f150 100644 --- a/remoting/remoting-triple/src/main/java/com/alipay/sofa/rpc/server/triple/GenericServiceImpl.java +++ b/remoting/remoting-triple/src/main/java/com/alipay/sofa/rpc/server/triple/GenericServiceImpl.java @@ -60,7 +60,6 @@ public GenericServiceImpl(Invoker invoker, ProviderConfig providerConfig) { this.invoker = invoker; this.providerConfig = providerConfig; String key = ConfigUniqueNameGenerator.getUniqueName(providerConfig); - ReflectCache.registerServiceClassLoader(key, providerConfig.getProxyClass().getClassLoader()); // 缓存接口的方法 for (Method m : providerConfig.getProxyClass().getMethods()) { ReflectCache.putOverloadMethodCache(key, m); @@ -76,7 +75,7 @@ public void generic(Request request, StreamObserver responseObserver) String methodName = sofaRequest.getMethodName(); try { String key = ConfigUniqueNameGenerator.getUniqueName(providerConfig); - ClassLoader interfaceClassLoader = ReflectCache.getServiceClassLoader(key); + ClassLoader interfaceClassLoader = providerConfig.getProxyClass().getClassLoader(); Thread.currentThread().setContextClassLoader(interfaceClassLoader); Class[] argTypes = getArgTypes(request); From 78615d73dc68dea605ee5828e04e5ff57dbb405a Mon Sep 17 00:00:00 2001 From: Orez Date: Wed, 22 Jun 2022 15:19:59 +0800 Subject: [PATCH 5/6] fix ReflectCache cannot refresh --- .../sofa/rpc/common/cache/ReflectCache.java | 6 +- .../rpc/common/cache/ReflectCacheTest.java | 67 +++++++++++++++++++ 2 files changed, 70 insertions(+), 3 deletions(-) create mode 100644 core/common/src/test/java/com/alipay/sofa/rpc/common/cache/ReflectCacheTest.java diff --git a/core/common/src/main/java/com/alipay/sofa/rpc/common/cache/ReflectCache.java b/core/common/src/main/java/com/alipay/sofa/rpc/common/cache/ReflectCache.java index 062c2c223..f9a02c8f5 100644 --- a/core/common/src/main/java/com/alipay/sofa/rpc/common/cache/ReflectCache.java +++ b/core/common/src/main/java/com/alipay/sofa/rpc/common/cache/ReflectCache.java @@ -195,7 +195,7 @@ public static void putMethodCache(String serviceName, Method method) { cache = old; } } - cache.putIfAbsent(method.getName(), method); + cache.put(method.getName(), method); } /** @@ -236,7 +236,7 @@ public static void putMethodSigsCache(String serviceName, String methodName, Str cacheSigs = old; } } - cacheSigs.putIfAbsent(methodName, argSigs); + cacheSigs.put(methodName, argSigs); } /** @@ -289,7 +289,7 @@ public static void putOverloadMethodCache(String serviceName, Method method) { for (Class paramType : method.getParameterTypes()) { mSigs.append(paramType.getName()); } - cache.putIfAbsent(mSigs.toString(), method); + cache.put(mSigs.toString(), method); } /** diff --git a/core/common/src/test/java/com/alipay/sofa/rpc/common/cache/ReflectCacheTest.java b/core/common/src/test/java/com/alipay/sofa/rpc/common/cache/ReflectCacheTest.java new file mode 100644 index 000000000..7b6754247 --- /dev/null +++ b/core/common/src/test/java/com/alipay/sofa/rpc/common/cache/ReflectCacheTest.java @@ -0,0 +1,67 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alipay.sofa.rpc.common.cache; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Test; + +import java.lang.reflect.Method; + +/** + * @author zhangchengxi + */ +public class ReflectCacheTest { + + @After + public void teardown() { + ReflectCache.clearAll(); + } + + @Test + public void putOverloadMethodCache() throws NoSuchMethodException { + Method hashCode1 = String.class.getMethod("hashCode"); + Method hashCode2 = Object.class.getMethod("hashCode"); + ReflectCache.putOverloadMethodCache("service", hashCode1); + Assert.assertSame(hashCode1, ReflectCache.getOverloadMethodCache("service", "hashCode", new String[]{})); + + ReflectCache.putOverloadMethodCache("service", hashCode2); + Assert.assertSame(hashCode2, ReflectCache.getOverloadMethodCache("service", "hashCode", new String[]{})); + } + + @Test + public void putMethodCache() throws NoSuchMethodException { + Method hashCode1 = String.class.getMethod("hashCode"); + Method hashCode2 = Object.class.getMethod("hashCode"); + ReflectCache.putMethodCache("service", hashCode1); + Assert.assertSame(hashCode1, ReflectCache.getMethodCache("service", "hashCode")); + + ReflectCache.putMethodCache("service", hashCode2); + Assert.assertSame(hashCode2, ReflectCache.getMethodCache("service", "hashCode")); + } + + @Test + public void putMethodSigsCache() throws NoSuchMethodException { + String[] sign1 = {"a"}; + String[] sign2 = {"b"}; + ReflectCache.putMethodSigsCache("service", "hashCode", sign1); + Assert.assertSame(sign1, ReflectCache.getMethodSigsCache("service", "hashCode")); + + ReflectCache.putMethodSigsCache("service", "hashCode", sign2); + Assert.assertSame(sign2, ReflectCache.getMethodSigsCache("service", "hashCode")); + } +} \ No newline at end of file From dff0d9ebc107b6d3b4605d67886dfc0efc1fd8b4 Mon Sep 17 00:00:00 2001 From: Orez Date: Wed, 22 Jun 2022 16:20:07 +0800 Subject: [PATCH 6/6] reformat --- .../alipay/sofa/rpc/common/cache/ReflectCacheTest.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/core/common/src/test/java/com/alipay/sofa/rpc/common/cache/ReflectCacheTest.java b/core/common/src/test/java/com/alipay/sofa/rpc/common/cache/ReflectCacheTest.java index 7b6754247..624b06a3a 100644 --- a/core/common/src/test/java/com/alipay/sofa/rpc/common/cache/ReflectCacheTest.java +++ b/core/common/src/test/java/com/alipay/sofa/rpc/common/cache/ReflectCacheTest.java @@ -37,10 +37,10 @@ public void putOverloadMethodCache() throws NoSuchMethodException { Method hashCode1 = String.class.getMethod("hashCode"); Method hashCode2 = Object.class.getMethod("hashCode"); ReflectCache.putOverloadMethodCache("service", hashCode1); - Assert.assertSame(hashCode1, ReflectCache.getOverloadMethodCache("service", "hashCode", new String[]{})); + Assert.assertSame(hashCode1, ReflectCache.getOverloadMethodCache("service", "hashCode", new String[] {})); ReflectCache.putOverloadMethodCache("service", hashCode2); - Assert.assertSame(hashCode2, ReflectCache.getOverloadMethodCache("service", "hashCode", new String[]{})); + Assert.assertSame(hashCode2, ReflectCache.getOverloadMethodCache("service", "hashCode", new String[] {})); } @Test @@ -56,8 +56,8 @@ public void putMethodCache() throws NoSuchMethodException { @Test public void putMethodSigsCache() throws NoSuchMethodException { - String[] sign1 = {"a"}; - String[] sign2 = {"b"}; + String[] sign1 = { "a" }; + String[] sign2 = { "b" }; ReflectCache.putMethodSigsCache("service", "hashCode", sign1); Assert.assertSame(sign1, ReflectCache.getMethodSigsCache("service", "hashCode"));