Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unexpected generic exception in triple #13368

Closed
focuse8 opened this issue Nov 15, 2023 · 7 comments
Closed

Unexpected generic exception in triple #13368

focuse8 opened this issue Nov 15, 2023 · 7 comments
Labels
type/bug Bugs to being fixed

Comments

@focuse8
Copy link

focuse8 commented Nov 15, 2023

When the second parameter of GenericService.$invoke is passed null, version 3.2.7 fills it with the parameter type of $invoke, causing the provider to not be able to find the corresponding method.

Environment

  • Dubbo version: 3.2.7
  • Operating System version: xxx
  • Java version: 1.8

Steps to reproduce this issue

  1. Set dubbo version 3.2.7
  2. Use triple protocol generics genericService.$invoke("methodName", null, new Object[])

Pls. provide [GitHub address] to reproduce this issue.

Expected Behavior

Return normally

Actual Behavior

The provider cannot find the corresponding method

Cause Analysis:
Use org.apache.dubbo.rpc.protocol.tri.TripleInvoker#invokeUnary to obtain the actual parameter type using

org.apache.dubbo.rpc.support.RpcUtils#getParameterTypes
public static Class<?>[] getParameterTypes(Invocation invocation) {
         if ($INVOKE.equals(invocation.getMethodName())
             && invocation.getArguments() != null
             && invocation.getArguments().length > 1
             && invocation.getArguments()[1] instanceof String[]) {
             String[] types = (String[]) invocation.getArguments()[1];
             if (types == null) {
                 return new Class<?>[0];
             }
             Class<?>[] parameterTypes = new Class<?>[types.length];
             for (int i = 0; i < types.length; i++) {
                 parameterTypes[i] = ReflectUtils.forName(types[i]);
             }
             return parameterTypes;
         }
         return invocation.getParameterTypes();
     }

If null is passed, invocation.getArguments()[1] instanceof String[] will not be established, resulting in the actual parameter type returned being a generic parameter type [String, Ljava.lang.String, Ljava.lang.Object]

The request received by the provider is as shown below,
image


Environment

  • Dubbo version: 3.2.7
  • Operating System version: xxx
  • Java version: 1.8

Steps to reproduce this issue

  1. 设置dubbo版本3.2.7
  2. triple协议泛型掉用 genericService.$invoke("methodName", null, new Object[])

Pls. provide [GitHub address] to reproduce this issue.

Expected Behavior

正常返回

Actual Behavior

提供者找不到对应方法

原因分析:
org.apache.dubbo.rpc.protocol.tri.TripleInvoker#invokeUnary 里面使用org.apache.dubbo.rpc.support.RpcUtils#getParameterTypes获取实际参数类型
public static Class[] getParameterTypes(Invocation invocation) { if ($INVOKE.equals(invocation.getMethodName()) && invocation.getArguments() != null && invocation.getArguments().length > 1 && invocation.getArguments()[1] instanceof String[]) { String[] types = (String[]) invocation.getArguments()[1]; if (types == null) { return new Class[0];
}
Class[] parameterTypes = new Class[types.length];
for (int i = 0; i < types.length; i++) {
parameterTypes[i] = ReflectUtils.forName(types[i]);
}
return parameterTypes;
}
return invocation.getParameterTypes();
}
如果传的是null,则 invocation.getArguments()[1] instanceof String[]不会成立,导致返回的实际参数类型泛型的参数类型 [String, Ljava.lang.String, Ljava.lang.Object]

提供者收到的请求如下图,
image

@focuse8 focuse8 added the type/bug Bugs to being fixed label Nov 15, 2023
@AlbumenJ AlbumenJ changed the title 3.2.7 triple协议泛型调用问题:GenericService.$invoke 第二个参数传null的时候,3.2.7版本用$invoke的参数类型填充,导致提供者找不到对应方法 Unexpected generic exception in triple Nov 16, 2023
@AlbumenJ
Copy link
Member

Can you please provider the error log including exception stack trace?

@focuse8
Copy link
Author

focuse8 commented Nov 17, 2023

Can you please provider the error log including exception stack trace?


Acturally, our method named ExperimentDetailApi.queryForGatewayRoute has only one object param, but in generics there are three params which acturally are the params of GenericService.$invoke.
The stack is as below:

Invocation of init method failed; nested exception is org.apache.dubbo.rpc.StatusRpcException: UNKNOWN : com......ExperimentDetailApi.queryForGatewayRoute(java.lang.String, [Ljava.lang.String;, [Ljava.lang.Object;)
org.apache.dubbo.rpc.RpcException: com......ExperimentDetailApi.queryForGatewayRoute(java.lang.String, [Ljava.lang.String;, [Ljava.lang.Object;)
	at org.apache.dubbo.rpc.filter.GenericFilter.invoke(GenericFilter.java:188)
	at org.apache.dubbo.rpc.cluster.filter.FilterChainBuilder$CopyOfFilterChainNode.invoke(FilterChainBuilder.java:326)
	at org.apache.dubbo.rpc.filter.ClassLoaderFilter.invoke(ClassLoaderFilter.java:54)
	at org.apache.dubbo.rpc.cluster.filter.FilterChainBuilder$CopyOfFilterChainNode.invoke(FilterChainBuilder.java:326)
	at org.apache.dubbo.rpc.filter.EchoFilter.invoke(EchoFilter.java:41)

	at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.postProcessProperties(CommonAnnotationBeanPostProcessor.java:321)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1420)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:593)

@AlbumenJ
Copy link
Member

Do you mean that you have defined a service which have the params like java.lang.String, [Ljava.lang.String;, [Ljava.lang.Object; or you have invoked a service by Dubbo generic service with GenericService interface?

@focuse8
Copy link
Author

focuse8 commented Nov 20, 2023

Do you mean that you have defined a service which have the params like java.lang.String, [Ljava.lang.String;, [Ljava.lang.Object; or you have invoked a service by Dubbo generic service with GenericService interface?

I have invoked a service with ’GenericService‘ interface. my service has just only one param, that is java.lang.Object. But when I invoked it using GenericService.$invoke("queryForGatewayRoute", null, args), the provider threw an NoSuchMethodExceptio. Because the provider received a request with three params java.lang.String, [Ljava.lang.String;, [Ljava.lang.Object;. As I debuged above, the org.apache.dubbo.rpc.support.RpcUtils#getParameterTypes method fills up params with java.lang.String, [Ljava.lang.String;, [Ljava.lang.Object; in dubbo 3.2.7.

@AlbumenJ
Copy link
Member

@icodening PTAL
Seems we should change the login in org/apache/dubbo/rpc/protocol/tri/TripleInvoker.java:267

@focuse8
Copy link
Author

focuse8 commented Dec 4, 2023

@icodening PTAL Seems we should change the login in org/apache/dubbo/rpc/protocol/tri/TripleInvoker.java:267

@AlbumenJ @icodening Which version would you fix this issue in ?

@AlbumenJ
Copy link
Member

AlbumenJ commented Dec 8, 2023

May fixed in #13442

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type/bug Bugs to being fixed
Projects
None yet
Development

No branches or pull requests

3 participants