前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >lombok1.16.20序列化bug分析

lombok1.16.20序列化bug分析

作者头像
方丈的寺院
发布2019-08-05 17:39:44
1.1K0
发布2019-08-05 17:39:44
举报
文章被收录于专栏:方丈的寺院

摘要

记录下使用 lombok遇到的反序列问题,一开始在 lombok1.16.18中并没有发现,然后应用中没有指定lombok全局版本,引入的其他二方包将lombok版本提升到了 1.16.20,然后报错。因为这个问题需要允许时才能发现,很可能会造成线上故障,所以不能等到出现问题时才发现,需要提前知晓。

错误栈

代码语言:javascript
复制
com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `com.fs.jackson.Address` (no Creators, like default construct, exist): cannot deserialize from Object value (no delegate- or property-based Creator)
 at [Source: (String)"{"id":1,"address":"address"}"; line: 1, column: 2]
    at com.fasterxml.jackson.databind.exc.InvalidDefinitionException.from(InvalidDefinitionException.java:67)
    at com.fasterxml.jackson.databind.DeserializationContext.reportBadDefinition(DeserializationContext.java:1451)
    at com.fasterxml.jackson.databind.DeserializationContext.handleMissingInstantiator(DeserializationContext.java:1027)
    at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromObjectUsingNonDefault(BeanDeserializerBase.java:1297)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:326)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:159)
    at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4013)
    at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3004)
    at Application.testSeriable(Application.java:36)
    at Application.run(Application.java:24)
    at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:790)
    at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:774)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:335)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1246)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1234)
    at Application.main(Application.java:27)

问题

问题1:

代码语言:javascript
复制
手贱把一个private修饰符写成了final

@Data
public class AddressVO {
     final Long id;
    private String address;
}

问题2 使用了Bulider类

代码语言:javascript
复制
@Data
@Accessors(chain = true)
@Builder
public class Address {
    private Long id;
    private String address;
}

分析

分析lombok导致的问题很简单,查看下编译后的class文件即可。使用 jd-gui反编译工具查看一下

1.6.18

代码语言:javascript
复制
public class AddressByBuilder {
    private Long id;
    private String address;

    public static class AddressBuilder {
        private Long id;
        private String address;
        // 省略
    }

    @ConstructorProperties({ "id", "address" })
    AddressByBuilder(Long id, String address) {
        this.id = id;
        this.address = address;
    }
}

1.16.20

代码语言:javascript
复制
public class AddressByLombok20 {

    private Long id;
    private String address;
    // 构造函数
    AddressByLombok20(Long id, String address) {
        this.id = id;
        this.address = address;
    }
}

对比1.16.28与1.16.20发现构造函数发生了变化。1.16.20中构造函数少了 @ConstructorProperties({"id","address"})JDK1.6中出来的

The annotation shows that the first parameter of the constructor can be retrieved with the getX() method and the second with the getY() method. Since parameter names are not in general available at runtime, without the annotation there would be no way to know whether the parameters correspond to getX() and getY() or the other way around.

@ConstructorProperties()注解用于构造函数上,表示构造函数可以通过GetName来找到,第一个参数可以使用getX()方法检索,第二个参数可以使用方法检索getY()。由于方法参数名一般在运行时不可见,如果没有标注就没有办法知道参数是否符合getX() 和getY()或周围的其他方法。

这显然是lombok升级过程中的一个不兼容的改造。

因为我们都没有定义无参构造函数,所以会找已有的构造函数,然后匹配getter/setter函数。

解决

1.maven中指定lombok固定版本,使用1.16.18版本,代码层面不需要做更改 2.类中添加无参构造器

建议

代码语言:javascript
复制
需要序列化的类,比如与前端交互,rpc调用,都加上无参构造器,兼容性比较好

参考

http://tutorials.jenkov.com/java-json/jackson-objectmapper.html#how-jackson-objectmapper-matches-json-fields-to-java-fields、

https://www.jianshu.com/p/f826ba2dbcf9

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-04-14,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 方丈的寺院 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 摘要
  • 问题
  • 分析
  • 解决
  • 参考
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档