這是我以前提的問題:問題連接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
若是已經開始大規模的使用那麼不妨使用別的類型,繞過這三個類型便可避免這個問題。源碼
問題來源於同事隨口問的一個小問題,挺感興趣就一直糾纏了下來,發現問題仍是挺嚴重的,另外借用同事的一句話,再也不維護的開源軟件真的挺危險。開源軟件