使用Jackson3反序列化PagedModel遇IllegalAccessError,如何保留AfterBurnerModule修复?
修复Jackson Afterburner模块与Spring HATEOAS PagedModel反序列化的IllegalAccessError问题
问题场景
使用依赖:
- jackson-module-afterburner (3.0.4)
- spring-hateoas (3.0.2)
执行以下代码将HATEOAS JSON反序列化为org.springframework.hateoas.PagedModel时,触发IllegalAccessError:
JsonMapper.builder() .addModule(new AfterburnerModule()) .addModule(new HalJacksonModule()) .build() .readValue(""" { "_embedded": { "dtoList": [{"id": 21}] }, "_links": { "self": {"href": "http://localhost:8080/api/dtos?page=0&size=20"} }, "page": { "number": 0, "size": 20, "totalElements": 1, "totalPages": 1 } }""", PagedModel.class)
异常日志:
java.lang.IllegalAccessError: class org.springframework.hateoas.PagedModel$Creator4JacksonDeserializere4fb0aac tried to access protected method 'void org.springframework.hateoas.PagedModel.<init>()' (org.springframework.hateoas.PagedModel$Creator4JacksonDeserializere4fb0aac is in unnamed module of loader tools.jackson.module.afterburner.util.MyClassLoader @55f3c410; org.springframework.hateoas.PagedModel is in unnamed module of loader 'app') at org.springframework.hateoas.PagedModel$Creator4JacksonDeserializere4fb0aac.createUsingDefault(Unknown Source) at tools.jackson.module.afterburner.deser.SuperSonicUnrolledDeserializer.deserializeFromObject(SuperSonicUnrolledDeserializer.java:369) at tools.jackson.databind.deser.bean.BeanDeserializer.deserialize(BeanDeserializer.java:200) at tools.jackson.module.afterburner.deser.SuperSonicUnrolledDeserializer.deserialize(SuperSonicUnrolledDeserializer.java:150) at tools.jackson.databind.deser.DeserializationContextExt.readRootValue(DeserializationContextExt.java:265) at tools.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:2611) at tools.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:1518)
问题核心:Afterburner模块用自定义类加载器生成的反序列化类,尝试访问PagedModel的无参保护构造方法,但类加载器隔离导致权限校验失败。
无需移除AfterburnerModule的修复方案
方案1:让Afterburner跳过PagedModel的优化
通过Afterburner模块的配置,排除PagedModel或整个Spring HATEOAS模型包使用优化逻辑,改用Jackson默认反序列化:
JsonMapper mapper = JsonMapper.builder() .addModule(new AfterburnerModule() // 排除单个类 .addDeserializationExclusion(PagedModel.class) // 可选:排除整个Spring HATEOAS模型包,避免后续其他类出问题 .addDeserializationExclusion("org.springframework.hateoas") .setUseValueClassLoader(false)) .addModule(new HalJacksonModule()) .build();
方案2:基于Spring HATEOAS预配置Mapper扩展
Spring HATEOAS自带适配Hal格式的ObjectMapper配置,在此基础上添加Afterburner并排除目标类:
// 初始化Spring HATEOAS适配的Mapper ObjectMapper hateoasMapper = new ObjectMapper(); hateoasMapper.registerModule(new Jackson2HalModule()); // 添加Afterburner并排除PagedModel优化 AfterburnerModule afterburnerModule = new AfterburnerModule(); afterburnerModule.addDeserializationExclusion(PagedModel.class); hateoasMapper.registerModule(afterburnerModule); // 执行反序列化 PagedModel<?> result = hateoasMapper.readValue(jsonString, PagedModel.class);
方案3:Java 9+模块化项目开放权限
如果是模块化项目,在module-info.java中给Afterburner模块开放PagedModel的构造方法访问权限:
module your.app.module { opens org.springframework.hateoas to tools.jackson.module.afterburner; }
内容的提问来源于stack exchange,提问作者wintenbb
相关产品推荐
相关产品推荐

