Fix dubbo get wrong return type when generic impl invoke (#10891)
This commit is contained in:
parent
dce55071c7
commit
305d290e5f
|
|
@ -78,10 +78,22 @@ public class RpcUtils {
|
|||
&& invocation.getInvoker().getUrl() != null
|
||||
&& invocation.getInvoker().getInterface() != GenericService.class
|
||||
&& !invocation.getMethodName().startsWith("$")) {
|
||||
Type[] returnTypes = null;
|
||||
if (invocation instanceof RpcInvocation) {
|
||||
returnTypes = ((RpcInvocation) invocation).getReturnTypes();
|
||||
if (returnTypes != null) {
|
||||
return returnTypes;
|
||||
}
|
||||
}
|
||||
String service = invocation.getInvoker().getUrl().getServiceInterface();
|
||||
if (StringUtils.isNotEmpty(service)) {
|
||||
Method method = getMethodByService(invocation, service);
|
||||
return ReflectUtils.getReturnTypes(method);
|
||||
if (method != null) {
|
||||
returnTypes = ReflectUtils.getReturnTypes(method);
|
||||
}
|
||||
}
|
||||
if (returnTypes != null) {
|
||||
return returnTypes;
|
||||
}
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ import java.util.HashMap;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.$INVOKE;
|
||||
import static org.apache.dubbo.rpc.Constants.AUTO_ATTACH_INVOCATIONID_KEY;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
|
|
@ -153,7 +154,7 @@ public class RpcUtilsTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testGetReturnTypes() throws Exception {
|
||||
public void testGetReturnTypesUseCache() throws Exception {
|
||||
Class<?> demoServiceClass = DemoService.class;
|
||||
String serviceName = demoServiceClass.getName();
|
||||
Invoker invoker = mock(Invoker.class);
|
||||
|
|
@ -216,6 +217,114 @@ public class RpcUtilsTest {
|
|||
Assertions.assertArrayEquals(types5, inv5.getReturnTypes());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetReturnTypesWithoutCache() throws Exception {
|
||||
Class<?> demoServiceClass = DemoService.class;
|
||||
String serviceName = demoServiceClass.getName();
|
||||
Invoker invoker = mock(Invoker.class);
|
||||
given(invoker.getUrl()).willReturn(URL.valueOf(
|
||||
"test://127.0.0.1:1/org.apache.dubbo.rpc.support.DemoService?interface=org.apache.dubbo.rpc.support.DemoService"));
|
||||
|
||||
RpcInvocation inv = new RpcInvocation("testReturnType", serviceName, "", new Class<?>[] {String.class}, null, null, invoker, null);
|
||||
inv.setReturnTypes(null);
|
||||
Type[] types = RpcUtils.getReturnTypes(inv);
|
||||
Assertions.assertNotNull(types);
|
||||
Assertions.assertEquals(2, types.length);
|
||||
Assertions.assertEquals(String.class, types[0]);
|
||||
Assertions.assertEquals(String.class, types[1]);
|
||||
|
||||
RpcInvocation inv1 =
|
||||
new RpcInvocation("testReturnType1", serviceName, "", new Class<?>[] {String.class}, null, null, invoker, null);
|
||||
inv1.setReturnTypes(null);
|
||||
java.lang.reflect.Type[] types1 = RpcUtils.getReturnTypes(inv1);
|
||||
Assertions.assertNotNull(types1);
|
||||
Assertions.assertEquals(2, types1.length);
|
||||
Assertions.assertEquals(List.class, types1[0]);
|
||||
Assertions.assertEquals(demoServiceClass.getMethod("testReturnType1", String.class).getGenericReturnType(), types1[1]);
|
||||
|
||||
RpcInvocation inv2 =
|
||||
new RpcInvocation("testReturnType2", serviceName, "", new Class<?>[] {String.class}, null, null, invoker, null);
|
||||
inv2.setReturnTypes(null);
|
||||
java.lang.reflect.Type[] types2 = RpcUtils.getReturnTypes(inv2);
|
||||
Assertions.assertNotNull(types2);
|
||||
Assertions.assertEquals(2, types2.length);
|
||||
Assertions.assertEquals(String.class, types2[0]);
|
||||
Assertions.assertEquals(String.class, types2[1]);
|
||||
|
||||
RpcInvocation inv3 =
|
||||
new RpcInvocation("testReturnType3", serviceName, "", new Class<?>[] {String.class}, null, null, invoker, null);
|
||||
inv3.setReturnTypes(null);
|
||||
java.lang.reflect.Type[] types3 = RpcUtils.getReturnTypes(inv3);
|
||||
Assertions.assertNotNull(types3);
|
||||
Assertions.assertEquals(2, types3.length);
|
||||
Assertions.assertEquals(List.class, types3[0]);
|
||||
java.lang.reflect.Type genericReturnType3 = demoServiceClass.getMethod("testReturnType3", String.class).getGenericReturnType();
|
||||
Assertions.assertEquals(((ParameterizedType) genericReturnType3).getActualTypeArguments()[0], types3[1]);
|
||||
|
||||
RpcInvocation inv4 =
|
||||
new RpcInvocation("testReturnType4", serviceName, "", new Class<?>[] {String.class}, null, null, invoker, null);
|
||||
inv4.setReturnTypes(null);
|
||||
java.lang.reflect.Type[] types4 = RpcUtils.getReturnTypes(inv4);
|
||||
Assertions.assertNotNull(types4);
|
||||
Assertions.assertEquals(2, types4.length);
|
||||
Assertions.assertNull(types4[0]);
|
||||
Assertions.assertNull(types4[1]);
|
||||
|
||||
RpcInvocation inv5 =
|
||||
new RpcInvocation("testReturnType5", serviceName, "", new Class<?>[] {String.class}, null, null, invoker, null);
|
||||
inv5.setReturnTypes(null);
|
||||
java.lang.reflect.Type[] types5 = RpcUtils.getReturnTypes(inv5);
|
||||
Assertions.assertNotNull(types5);
|
||||
Assertions.assertEquals(2, types5.length);
|
||||
Assertions.assertEquals(Map.class, types5[0]);
|
||||
java.lang.reflect.Type genericReturnType5 = demoServiceClass.getMethod("testReturnType5", String.class).getGenericReturnType();
|
||||
Assertions.assertEquals(((ParameterizedType) genericReturnType5).getActualTypeArguments()[0], types5[1]);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testGetReturnTypesWhenGeneric() throws Exception {
|
||||
Class<?> demoServiceClass = DemoService.class;
|
||||
String serviceName = demoServiceClass.getName();
|
||||
Invoker invoker = mock(Invoker.class);
|
||||
given(invoker.getUrl()).willReturn(URL.valueOf(
|
||||
"test://127.0.0.1:1/org.apache.dubbo.rpc.support.DemoService?interface=org.apache.dubbo.rpc.support.DemoService"));
|
||||
|
||||
RpcInvocation inv = new RpcInvocation("testReturnType", serviceName, "", new Class<?>[] {String.class}, null, null, invoker, null);
|
||||
inv.setMethodName($INVOKE);
|
||||
Type[] types = RpcUtils.getReturnTypes(inv);
|
||||
Assertions.assertNull(types);
|
||||
|
||||
RpcInvocation inv1 =
|
||||
new RpcInvocation("testReturnType1", serviceName, "", new Class<?>[] {String.class}, null, null, invoker, null);
|
||||
inv1.setMethodName($INVOKE);
|
||||
java.lang.reflect.Type[] types1 = RpcUtils.getReturnTypes(inv1);
|
||||
Assertions.assertNull(types1);
|
||||
|
||||
RpcInvocation inv2 =
|
||||
new RpcInvocation("testReturnType2", serviceName, "", new Class<?>[] {String.class}, null, null, invoker, null);
|
||||
inv2.setMethodName($INVOKE);
|
||||
java.lang.reflect.Type[] types2 = RpcUtils.getReturnTypes(inv2);
|
||||
Assertions.assertNull(types2);
|
||||
|
||||
RpcInvocation inv3 =
|
||||
new RpcInvocation("testReturnType3", serviceName, "", new Class<?>[] {String.class}, null, null, invoker, null);
|
||||
inv3.setMethodName($INVOKE);
|
||||
java.lang.reflect.Type[] types3 = RpcUtils.getReturnTypes(inv3);
|
||||
Assertions.assertNull(types3);
|
||||
|
||||
RpcInvocation inv4 =
|
||||
new RpcInvocation("testReturnType4", serviceName, "", new Class<?>[] {String.class}, null, null, invoker, null);
|
||||
inv4.setMethodName($INVOKE);
|
||||
java.lang.reflect.Type[] types4 = RpcUtils.getReturnTypes(inv4);
|
||||
Assertions.assertNull(types4);
|
||||
|
||||
RpcInvocation inv5 =
|
||||
new RpcInvocation("testReturnType5", serviceName, "", new Class<?>[] {String.class}, null, null, invoker, null);
|
||||
inv5.setMethodName($INVOKE);
|
||||
java.lang.reflect.Type[] types5 = RpcUtils.getReturnTypes(inv5);
|
||||
Assertions.assertNull(types5);
|
||||
}
|
||||
@Test
|
||||
public void testGetParameterTypes() {
|
||||
Class<?> demoServiceClass = DemoService.class;
|
||||
|
|
|
|||
|
|
@ -32,7 +32,6 @@ import org.apache.dubbo.remoting.exchange.Response;
|
|||
import org.apache.dubbo.remoting.transport.CodecSupport;
|
||||
import org.apache.dubbo.rpc.AppResponse;
|
||||
import org.apache.dubbo.rpc.Invocation;
|
||||
import org.apache.dubbo.rpc.RpcInvocation;
|
||||
import org.apache.dubbo.rpc.support.RpcUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
|
|
@ -151,15 +150,10 @@ public class DecodeableRpcResult extends AppResponse implements Codec, Decodeabl
|
|||
|
||||
private void handleValue(ObjectInput in) throws IOException {
|
||||
try {
|
||||
Type[] returnTypes;
|
||||
if (invocation instanceof RpcInvocation) {
|
||||
returnTypes = ((RpcInvocation) invocation).getReturnTypes();
|
||||
} else {
|
||||
returnTypes = RpcUtils.getReturnTypes(invocation);
|
||||
}
|
||||
Type[] returnTypes = RpcUtils.getReturnTypes(invocation);
|
||||
Object value;
|
||||
if (ArrayUtils.isEmpty(returnTypes)) {
|
||||
// This almost never happens?
|
||||
// happens when generic invoke or void return
|
||||
value = in.readObject();
|
||||
} else if (returnTypes.length == 1) {
|
||||
value = in.readObject((Class<?>) returnTypes[0]);
|
||||
|
|
|
|||
|
|
@ -32,7 +32,6 @@ public interface ObjectInput extends DataInput {
|
|||
* @throws IOException if an I/O error occurs
|
||||
* @throws ClassNotFoundException if an ClassNotFoundException occurs
|
||||
*/
|
||||
@Deprecated
|
||||
Object readObject() throws IOException, ClassNotFoundException;
|
||||
|
||||
/**
|
||||
|
|
|
|||
Loading…
Reference in New Issue