Spring Boot 3 Native中Lombok @Value类反序列化失败求助
问题根源
GraalVM构建原生镜像时会执行静态代码分析,Lombok动态生成的ExampleDto$ExampleDtoBuilder类及其build()方法未被纳入GraalVM的反射元数据白名单,导致Jackson在反序列化POST请求的JSON时,无法通过反射找到该方法,进而抛出HttpMediaTypeNotSupportedException。而@Data生成的get/set属于标准JavaBean规范,Spring Boot原生镜像的自动配置已覆盖这类场景,因此不会出现问题。
解决方法
1. 添加GraalVM反射元数据配置
在src/main/resources/META-INF/native-image目录下创建reflect-config.json文件,手动声明Builder类和build方法的反射权限:
[ { "name": "com.example.demo.dto.ExampleDto$ExampleDtoBuilder", "methods": [ { "name": "build", "parameterTypes": [] } ] } ]
注意替换com.example.demo.dto为你项目中实际的DTO包路径。
2. 升级Lombok至兼容版本
使用Lombok 1.18.30及以上稳定版本,该版本针对Spring Boot 3和GraalVM原生镜像的兼容性做了优化,能减少动态代码生成带来的元数据缺失问题。
3. 借助Spring AOT自动生成元数据
两种方式可选:
- 在主启动类添加
@NativeHint注解,指定Builder类的反射访问权限:
@SpringBootApplication @NativeHint( types = @TypeHint(typeNames = "com.example.demo.dto.ExampleDto$ExampleDtoBuilder", access = AccessBits.ALL) ) public class DemoApplication { public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } }
- 执行
mvn spring-boot:process-aot命令,让Spring Boot自动扫描并生成所有原生镜像所需的元数据,包括Lombok动态生成的类和方法,无需手动编写配置文件。
4. 确认构建命令正确性
保持使用指定的原生镜像构建命令:
mvn -Pnative native:build
额外说明
@Jacksonized注解本身会生成Jackson所需的序列化/反序列化器,但GraalVM的静态分析无法识别Lombok动态生成的字节码,因此必须通过元数据配置或Spring AOT来告知GraalVM相关类和方法的存在。另外,GET请求正常是因为GET场景仅需将实体序列化为JSON,而POST请求需要将JSON反序列化为DTO对象,这个过程会调用Builder的build()方法,而该方法的反射权限未被GraalVM允许,才导致报错。
内容的提问来源于stack exchange,提问作者Merch0

