背景:使用dubbo服务调用的时候,服务者端报Got unchecked and undeclared exception which called by xxx.xxx.xxx.xxx service: com.xxx.xxx.UserLoginService, method: Userlogin, exception: java.lang.NullPointerException: null, dubbo version: 2.5.3, current host: 127.0.0.1
详细异常堆栈如下:
ERROR com.alibaba.dubbo.rpc.filter.ExceptionFilter - [DUBBO] Got unchecked and undeclared exception which called by xxx.xxx.xxx.xxx service: com.xxx.xxx.UserLoginService, method: UserLogin, exception: java.lang.NullPointerException: null, dubbo version: 2.5.3, current host: 127.0.0.1
java.lang.NullPointerException
at java.util.Hashtable.put(Hashtable.java:459)
at org.apache.log4j.MDC.put0(MDC.java:117)
at org.apache.log4j.MDC.put(MDC.java:72)
at org.slf4j.impl.Log4jMDCAdapter.put(Log4jMDCAdapter.java:35)
at org.slf4j.MDC.put(MDC.java:116)
at com.xxx.service.aop.LogsAspect.initMDC(ReqAspect.java:72)
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:497)
at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:629)
at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:618)
at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAroundAdvice.java:70)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:673)
分析:一开始看到dubbo服务端报的异常,没细看,还以为是服务挂了,上了dubbo-admin控制台确认了一波,消费者跟服务者都正常运行;细看了,异常堆栈里面报 java.lang.NullPointerException,明显是空指针异常,在异常堆栈里找到自己代码出的异常提示at com.xxx.service.aop.LogsAspect.initMDC(ReqAspect.java:72),问题就出在这里,这里主要是切面里为每次请求进来添加一个全局的流水号,内如有一处有坑:
MDC.put(LOGCONFIG.TRACE_LOG_ID, traceLogId);这里使用的slf包是slf4j-api:1.7.5,有一个很致命的坑,这个版本的MDC的put进去的value值不能为null,不然会报 java.lang.NullPointerException,参考链接:https://www.eclipse.org/forums/index.php?t=msg&th=1078299&goto=1734728&#msg_1734728,
解决方法:把slf4j-api的依赖包升级为高版本,如:
<dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>1.7.26</version> </dependency>