这是我以前提的问题:问题连接java
在使用dubbo 2.5.3的时候,定义的接口中有一个方法使用了实体类做为参数,而这个实体类中定义了一个变量为java.sql.Time类型。不妨暂且定义接口以下:sql
//BusinessDto中有一个属性dealTime 为java.sql.Time类型 String queryBusiness(BusinessDto param);
当消费者调用这个接口的时候,若是param中的dealTime为null,那么在提供者那里接收到的整个param都为null,若是这个属性不为null,那么参数能够正常的传递。segmentfault
问题出在反序列化的时候。
dubbo使用的序列化是hession2的,而hession2对于Time类的反序列化的源码以下:函数
static class SqlTimeFieldDeserializer extends FieldDeserializer { private final Field _field; SqlTimeFieldDeserializer(Field field) { _field = field; } void deserialize(AbstractHessianInput in, Object obj) throws IOException { java.sql.Time value = null; try { java.util.Date date = (java.util.Date) in.readObject(); value = new java.sql.Time(date.getTime()); _field.set(obj, value); } catch (Exception e) { logDeserializeError(_field, obj, value, e); } } }
这里咱们能够清楚地看出来,将in读取到的object转为Date而后调用了getTime方法,那么若是咱们的dealTime属性为空,那么调用getTime函数必然会抛异常,也就产生了以后的结果。code
我找到的源码能够看出,对于 java.sql.Date, java.sql.Timestamp, java.sql.Time的反序列化均有问题存在。接口
static class SqlDateFieldDeserializer extends FieldDeserializer { private final Field _field; SqlDateFieldDeserializer(Field field) { _field = field; } void deserialize(AbstractHessianInput in, Object obj) throws IOException { java.sql.Date value = null; try { java.util.Date date = (java.util.Date) in.readObject(); value = new java.sql.Date(date.getTime()); _field.set(obj, value); } catch (Exception e) { logDeserializeError(_field, obj, value, e); } } } static class SqlTimestampFieldDeserializer extends FieldDeserializer { private final Field _field; SqlTimestampFieldDeserializer(Field field) { _field = field; } void deserialize(AbstractHessianInput in, Object obj) throws IOException { java.sql.Timestamp value = null; try { java.util.Date date = (java.util.Date) in.readObject(); value = new java.sql.Timestamp(date.getTime()); _field.set(obj, value); } catch (Exception e) { logDeserializeError(_field, obj, value, e); } } } static class SqlTimeFieldDeserializer extends FieldDeserializer { private final Field _field; SqlTimeFieldDeserializer(Field field) { _field = field; } void deserialize(AbstractHessianInput in, Object obj) throws IOException { java.sql.Time value = null; try { java.util.Date date = (java.util.Date) in.readObject(); value = new java.sql.Time(date.getTime()); _field.set(obj, value); } catch (Exception e) { logDeserializeError(_field, obj, value, e); } } }
而hessian4 则修复了这个问题,在调用getTime以前作了非空判断,若是为空则把这个属性赋null而不是产生异常。get
若是已经开始大规模的使用那么不妨使用别的类型,绕过这三个类型便可避免这个问题。源码
问题来源于同事随口问的一个小问题,挺感兴趣就一直纠缠了下来,发现问题仍是挺严重的,另外借用同事的一句话,再也不维护的开源软件真的挺危险。开源软件