某个跑数据的接口日志里发现了如下日常:
[ New I/O client worker #1-1:158555 ] - [ WARN ] com.alibaba.dubbo.rpc.protocol.dubbo.DecodeableRpcResult.decode(DecodeableRpcResult.java:116) [DUBBO] Decode rpc result failed: 'org.springframework.expression.spel.SpelEvaluationException' could not be instantiated, dubbo version: 2.6.2, current host: 192.168.x.x
com.alibaba.com.caucho.hessian.io.HessianProtocolException: 'org.springframework.expression.spel.SpelEvaluationException' could not be instantiated
at com.alibaba.com.caucho.hessian.io.JavaDeserializer.instantiate(JavaDeserializer.java:316)
at com.alibaba.com.caucho.hessian.io.JavaDeserializer.readObject(JavaDeserializer.java:201)
at com.alibaba.com.caucho.hessian.io.SerializerFactory.readObject(SerializerFactory.java:526)
...
Caused by: java.lang.reflect.InvocationTargetException
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at com.alibaba.com.caucho.hessian.io.JavaDeserializer.instantiate(JavaDeserializer.java:312)
... 28 more
Caused by: java.lang.NullPointerException
at org.springframework.expression.spel.SpelEvaluationException.<init>(SpelEvaluationException.java:37)
... 33 more
进一步在其调用的Dubbo接口所在的应用日志查看:
|ERROR|DubboServerHandler-192.168:x.x:xxx-thread-488|c.a.d.r.f.ExceptionFilter:85
[DUBBO] Got unchecked and undeclared exception which called by 192.168.x.x. service: com.biz.XxxService, method: xxx, exception: org.springframework.expression.spel.SpelEvaluationException: EL1007E:(pos 0): Property or field 'createTimestamp' cannot be found on null, dubbo version: x, current host: 192.168.x.x
org.springframework.expression.spel.SpelEvaluationException: EL1007E:(pos 0): Property or field 'createTimestamp' cannot be found on null
at org.springframework.expression.spel.ast.PropertyOrFieldReference.readProperty(PropertyOrFieldReference.java:220)
at org.springframework.expression.spel.ast.PropertyOrFieldReference.getValueInternal(PropertyOrFieldReference.java:94)
at org.springframework.expression.spel.ast.PropertyOrFieldReference.getValueInternal(PropertyOrFieldReference.java:81)
at org.springframework.expression.spel.ast.SpelNodeImpl.getValue(SpelNodeImpl.java:120)
at org.springframework.expression.spel.standard.SpelExpression.getValue(SpelExpression.java:242)
at com.xxx.ExpressionUtil...
...
某个转换使用了Spring的Express表达式,其中对象为null时,抛了一个SpelEvaluationException
异常,
在org.springframework.expression.spel.ast.PropertyOrFieldReference
的220行:
if (contextObject.getValue() == null) {
throw new SpelEvaluationException(SpelMessage.PROPERTY_OR_FIELD_NOT_READABLE_ON_NULL, name);
}
SpelEvaluationException
最终继承与EvaluationException
,但它本身缺少了无参构造函数,因此在Dubbo的调用方提示不能实例化。
解决方法:
- 修正通过Spring的Express表达式处理,增量null值判断;
- 捕获
SpelEvaluationException
,转换为该服务的业务异常。