Gradle引入logstash-logback-encoder依赖后测试因Jackson序列化失败
冲突根本原因
- 版本不一致触发类加载优先级异常:Wildfly 15 内置自带了 Jackson 2.x 版本以及 Resteasy 对应的 Jackson 序列化提供者
ResteasyJackson2Provider,默认采用父类优先的类加载策略,优先加载容器提供的 Jackson 相关类。你引入logstash-logback-encoder:6.6后,它传递依赖的jackson-databind:2.12.0把你项目原有 Jackson 全家桶版本从 2.10.4 抬升到了 2.12.0,直接导致容器提供的 Jackson 核心类、应用提供的 Jackson 扩展模块(jsr310)版本不匹配。 - ObjectMapper 未注册JSR310模块:Resteasy 内置的
ResteasyJackson2Provider构造全局 ObjectMapper 时,默认不会主动调用findAndRegisterModules()扫描类路径下的 Jackson 扩展模块。你之前版本能正常工作是因为项目自定义了 ObjectMapper 并手动注册了 JSR310 模块,版本抬升后自定义的 ObjectMapper 因为类加载冲突失效,降级到了容器默认无 JSR310 模块的 ObjectMapper,因此序列化 LocalDateTime 时报错。 - 日志依赖影响REST序列化的核心逻辑:二者共同依赖Jackson核心包,依赖版本变动会触发整个应用的Jackson类加载行为变化,并不是日志依赖直接修改了REST序列化规则。
解决方案
方案1:排除logstash传递依赖的Jackson(最稳妥,优先推荐)
适配容器内置版本,避免自行引入的Jackson和容器内置版本冲突,只要容器内置的Jackson版本 >= logstash要求的最低版本(logstash 6.6兼容Jackson 2.10+,刚好匹配你原有2.10.4版本)即可正常工作,原有REST序列化逻辑完全不受影响。
在build.gradle中调整依赖声明:
runtimeOnly('net.logstash.logback:logstash-logback-encoder:6.6') { exclude group: 'com.fasterxml.jackson.core' }
方案2:强制Resteasy使用自定义ObjectMapper
如果你确实需要使用高版本Jackson,可以显式注册自定义的Jackson提供者覆盖容器默认配置:
- 编写自定义Jackson提供者
@Provider @Produces(MediaType.APPLICATION_JSON) public class CustomJacksonProvider extends ResteasyJackson2Provider { public CustomJacksonProvider() { ObjectMapper mapper = new ObjectMapper() .registerModule(new JavaTimeModule()) .disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); setMapper(mapper); } }
- 在
WEB-INF/jboss-deployment-structure.xml中排除容器自带的Jackson相关组件,强制使用应用内版本:
<jboss-deployment-structure> <deployment> <exclusions> <module name="com.fasterxml.jackson.core.jackson-annotations" /> <module name="com.fasterxml.jackson.core.jackson-core" /> <module name="com.fasterxml.jackson.core.jackson-databind" /> <module name="com.fasterxml.jackson.datatype.jackson-datatype-jsr310" /> <module name="org.jboss.resteasy.resteasy-jackson2-provider" /> </exclusions> </deployment> </jboss-deployment-structure>
内容的提问来源于stack exchange,提问作者Vincent F
相关产品推荐
相关产品推荐

