记一个因为依赖管理糟糕踩的坑

事出有因

// 这段代码是 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

    fastjson.jar

  • 这里又关系到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的时候的断点,经过线程的栈帧和栈帧中的数据,足以说明个人推测一是正确的,为个人直觉感到欣慰!运维

frame
frame
相关文章
相关标签/搜索