Allatori代码混淆导致反序列化失败, 排查和解决

背景

项目在本地运行时调用Feign接口, 返回信息正确; 但是一旦线上部署运行, 就会发现对象的信息没有正确赋值; 本地Debug的时候也一直无法重现, 接下来便排查这个问题

过程

使用阿里的jvm工具 Arthas发现返回的对象, 字段名称已经被混淆掉了. 结合jackson反序列时的特性(先使用get/set,在使用field), 不难定位到问题所在, 返回的bean字段缺少了set方法

  • Arthas排查命令: watch com.demo.xx queryUserPage "{returnObj}" -x 2
  • jackson反序列化源码
    通过SettableBeanProperty进行属性赋值, MethodProperty缺失时使用FieldProperty, 这就不难解释为何本地无法重现, 因为本地运行的class没有被混淆, 可以通过字段名称进行赋值; 但是打包之后字段信息已经被抹除了所以无法赋值

demo验证

编写测试的bean --> 混淆打包, 配置参考 --> IDEA右键jar包, Add as Library --> 运行demo代码 , name属性为空

User类

public class User {
    private String name, city;
    public User() {
    }
    public User(String name) {
        this.name = name;
    }
   //name不提供set方法
}

Demo类

    public static void main(String[] args) throws JsonProcessingException {
        ObjectMapper mapper = new ObjectMapper();
        mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);

        User user = new User("jaychou").setCity("taibei");
        String str = mapper.writeValueAsString(user);
        //反序列化,name的值没有读取出来
        User parseUser = mapper.readValue(str, User.class);
        assert parseUser.getName() == null;
    }

解决

提供set方法, 或者不使用混淆

你可能感兴趣的:(Allatori代码混淆导致反序列化失败, 排查和解决)