apache / dubbo

The java implementation of Apache Dubbo. An RPC and microservice framework.
https://dubbo.apache.org/
Apache License 2.0
40.48k stars 26.43k forks source link

[Enhancement] ReferenceBeanInvocationHandler invoke proxy 没有捕获InvocationTargetException #3275

Closed cyejing closed 5 years ago

cyejing commented 5 years ago

Environment

Steps to reproduce this issue

  1. 客户端调用服务端发生异常,异常往上抛
  2. ReferenceAnnotationBeanPostProcessor$ReferenceBeanInvocationHandler 代理之后没有catch InvocationTargetException 取得 getTargetException 导致到业务代码之后无法获得到真实的异常

Pls. provide [GitHub address] to reproduce this issue. https://github.com/apache/incubator-dubbo/blob/3375ec827845a0b133eae1fd4aad78aeb203361a/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/beans/factory/annotation/ReferenceAnnotationBeanPostProcessor.java#L159

Expected Result

取得真实的异常信息,而不是 InvocationTargetException

Actual Result

到业务层代码的异常时UndeclaredThrowableException ->cause-> InvocationTargetException ->cause-> 真实的异常

If there is an exception, please attach the exception trace:

java.lang.reflect.UndeclaredThrowableException: null
    at com.sun.proxy.$Proxy78.sendSmsForSign(Unknown Source)
    at com.rttx.mobile.app.test.AppRnVersionTest.asd(AppRnVersionTest.java:54)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
    at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
    at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:252)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:94)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
    at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:191)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
    at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
Caused by: java.lang.reflect.InvocationTargetException: null
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at com.alibaba.dubbo.config.spring.beans.factory.annotation.ReferenceAnnotationBeanPostProcessor$ReferenceBeanInvocationHandler.invoke(ReferenceAnnotationBeanPostProcessor.java:159)
    ... 30 common frames omitted
Caused by: com.alibaba.dubbo.rpc.RpcException: Failfast invoke providers dubbo://172.31.9.150:11987/com.rttx.hades.api.pay.xxx?anyhost=true&application=MobileApp&bean.name=ServiceBean:com.rttx.hades.api.pay.PayService&check=false&default.check=false&default.cluster=failfast&default.proxy=jdk&default.retries=0&default.timeout=180000&dispatcher=message&dubbo=2.0.2&generic=false&interface=com.rttx.hades.api.pay.PayService&logger=slf4j&methods=xxx&pid=39213&proxy=jdk&register.ip=xxx&remote.timestamp=1547881625916&revision=1.0.0-SNAPSHOT&serialization=hessian2&side=consumer&timestamp=1547883670035 RandomLoadBalance select from all providers [com.alibaba.dubbo.registry.integration.RegistryDirectory$InvokerDelegate@e4348c0] for service com.rttx.hades.api.pay.xxx method xxx on consumer xxx use dubbo version 2.6.5, but no luck to perform the invocation. Last error is: xxx
    at com.alibaba.dubbo.rpc.cluster.support.FailfastClusterInvoker.doInvoke(FailfastClusterInvoker.java:53)
    at com.alibaba.dubbo.rpc.cluster.support.AbstractClusterInvoker.invoke(AbstractClusterInvoker.java:244)
    at com.alibaba.dubbo.rpc.cluster.support.wrapper.MockClusterInvoker.invoke(MockClusterInvoker.java:75)
    at com.alibaba.dubbo.rpc.proxy.InvokerInvocationHandler.invoke(InvokerInvocationHandler.java:52)
    at com.sun.proxy.$Proxy77.sendSmsForSign(Unknown Source)
    ... 35 common frames omitted
Caused by: java.lang.RuntimeException: xxxx
magang0425 commented 5 years ago

@cyejing 现在是怎么解决的

mercyblitz commented 5 years ago

Same issue #3386

scm1219 commented 5 years ago

@magang0425 这样

@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    try{
        return method.invoke(bean, args);
    }catch(InvocationTargetException ite){
        throw ite.getTargetException();
    }
}
cyejing commented 5 years ago

@magang0425 我选择重写 ReferenceAnnotationBeanPostProcessor 方法 如@scm1219 的代码。 等新版修复