// 這段代碼是 web 項目的 online 會調用
public void someMethod(long uid){
set.add(uid);
po.setString(JSON.toJSONString(set));
}
複製代碼
someMethod(long)
很簡單,就是將存儲 uid 的Set<Long>
經過 fastjson 轉成String
咋一看沒什麼問題,可是在反序列化的時候,uid 會默認爲Integer
這個時候就有類型強轉問題了。因此須要改爲JSON.toJSONString(set, SerializerFeature.WriteClassName)
附加類型名。這樣的String
就是Set[1234567890L]
那麼反序列化也OK了改完以後本地確實沒有問題,上線後 web 項目也沒問題,可是 online 項目在反序列化的時候就報錯了 com.alibaba.fastjson.JSONException: exepct '[', but error
查了半天,最後懷疑線上 online 的jar
包有問題,聯繫運維查了下 online 的classpath
,不出所料,當時心裏十分日狗 java
這裏又關係到class
的加載問題,可是很明顯 online 用的是 1.1.2 的版本,推測緣由有二:linux
File#compareTo(File pathname)
最後調用的仍是String#CaseInsensitiveComparator#compare(String, String)
linux
默認的,因此classloader
加載的時候會判斷,若是已經加載過同包同類的class
,則不加載後者其實這個問題就是依賴管理糟糕的坑,至於爲何線上 online 會有兩個 fastjson ,我也問了運維,歷史緣由。可是,若是是用maven
管理依賴,應該會避免此類問題web
仍是想搞清楚到底怎麼回事!json
下面兩個圖是在加載 jre\lib\ext\*.jar
的時候的斷點,經過線程的棧幀和棧幀中的數據,足以說明個人推測一是正確的,爲個人直覺感到欣慰!運維