升级Jackson至2.15.3后使用Record报"no delegate- or property-based Creator"错误
Jackson 2.15.3升级后Java Record反序列化失败问题解析
问题场景
以下代码在Jackson 2.14.3中可正常运行,但升级至2.15.3后抛出反序列化异常:
import com.fasterxml.jackson.annotation.JsonAutoDetect; import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.databind.ObjectMapper; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; class JacksonTest { @Test void test() { var str = """ {"id" : "test-rest"} """; var objectMapper = new BaseObjectMapper(); try { System.out.println(objectMapper.readValue(str, TestResp.class)); } catch (Exception e) { e.printStackTrace(); Assertions.fail(); } } record TestResp(String id) {} private static class BaseObjectMapper extends ObjectMapper { BaseObjectMapper() { setVisibility( getSerializationConfig() .getDefaultVisibilityChecker() .withFieldVisibility(JsonAutoDetect.Visibility.ANY) .withGetterVisibility(JsonAutoDetect.Visibility.NONE) .withIsGetterVisibility(JsonAutoDetect.Visibility.NONE) .withSetterVisibility(JsonAutoDetect.Visibility.NONE) .withCreatorVisibility(JsonAutoDetect.Visibility.NONE)) .setSerializationInclusion(Include.NON_NULL); } } }
抛出的异常信息:
com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `com.spotnana.obt.master.apis.auth.authentication.JacksonTest$TestResp` (no Creators, like default constructor, exist): cannot deserialize from Object value (no delegate- or property-based Creator) at [Source: (String)" {"id" : "test-rest"} "; line: 1, column: 4] at com.fasterxml.jackson.databind.exc.InvalidDefinitionException.from(InvalidDefinitionException.java:67) at com.fasterxml.jackson.databind.DeserializationContext.reportBadDefinition(DeserializationContext.java:1915) at com.fasterxml.jackson.databind.DatabindContext.reportBadDefinition(DatabindContext.java:414) at com.fasterxml.jackson.databind.DeserializationContext.handleMissingInstantiator(DeserializationContext.java:1360) at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromObjectUsingNonDefault(BeanDeserializerBase.java:1424) at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:352) at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:185) at com.fasterxml.jackson.databind.deser.DefaultDeserializationContext.readRootValue(DefaultDeserializationContext.java:323) at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4825) at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3772) at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3740) at com.spotnana.obt.master.apis.auth.authentication.JacksonTest.test(JacksonTest.java:19)
问题解答
1. 现象是否属于预期情况?
是,这是Jackson 2.15.3中的预期行为。
2. 导致问题的变更点
Jackson 2.15.x版本对Java Record的反序列化逻辑做了规则调整:
- 在2.14.x及更早版本中,Jackson会对Java Record做特殊处理:即使配置了
CreatorVisibility.NONE,依然会绕过可见性检查,自动使用Record的隐含构造器完成反序列化。 - 2.15.x版本开始,Record的构造器会严格遵守全局配置的
CreatorVisibility规则。你的代码中设置了withCreatorVisibility(JsonAutoDetect.Visibility.NONE),直接禁止Jackson访问所有用于创建实例的构造器、工厂方法,因此无法实例化TestRespRecord类,最终抛出异常。
内容的提问来源于stack exchange,提问作者tuk
相关产品推荐
相关产品推荐

