You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SpringBoot自定义JSON序列化/反序列化在GitLab CI/CD部署Docker时失效,Jenkins正常

SpringBoot自定义Jackson序列化逻辑失效故障排查

项目基础上下文

  • 框架版本:SpringBoot 2.3.1.RELEASE
  • 核心Gradle依赖配置:
dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-actuator'
    implementation 'org.springframework.boot:spring-boot-starter-web'
    implementation 'org.springframework.boot:spring-boot-starter-tomcat'
}
  • 技术栈默认规则:引入spring-boot-starter-web依赖后,项目默认内置Jackson库完成全链路JSON序列化、反序列化处理,前后端交互全量采用JSON格式通信。
  • 标准化发布流程:
    1. 从Git分支拉取最新代码
    2. 通过Gradle Wrapper完成项目构建
    3. 基于构建产出的Jar包,通过预置Dockerfile构建应用Docker镜像
    4. 通过docker-compose.yml启动运行新构建的Docker镜像

故障异常表现

  • 触发条件:GitLab CI/CD流水线完成Docker镜像构建、容器正常启动后,自定义的JSON序列化/反序列化逻辑完全不生效
  • 具体报错日志:
Exception--------org.springframework.http.converter.HttpMessageNotReadableException 
org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Cannot deserialize value of type "java.time.LocalDate" from String "20210412": Failed to deserialize java.time.LocalDate: (java.time.format.DateTimeParseException) Text '20210412' could not be parsed at index 0; nested exception is com.fasterxml.jackson.databind.exc.InvalidFormatException: Cannot deserialize value of type "java.time.LocalDate" from String "20210412": Failed to deserialize java.time.LocalDate: (java.time.format.DateTimeParseException) Text '20210412' could not be parsed at index 0
  • 反常对比特征:同一台物理服务器上,基于完全相同的代码文件构建,Jenkins流水线与GitLab CI/CD流水线产出的服务运行效果存在明确差异:
    • 两流程唯一差异点:代码存放目录不同、构建产出文件属主不同(Jenkins流程文件属主为root:root,GitLab CI/CD流程相关文件属主为gitlab-runner:gitlab-runner)
    • 两流程完全一致的配置:使用同一份Dockerfile、同一份docker-compose.yml配置,Docker镜像构建、服务启动流程均能正常完成,无构建报错、启动报错
    • 故障排他性:仅GitLab CI/CD流水线产出的服务实例存在自定义JSON序列化/反序列化失效问题,Jenkins流水线产出的同版本服务运行完全正常
    • 核心矛盾点:两流程使用完全一致的代码、Docker配置、运行环境,仅构建执行的系统用户、文件目录属主存在差异,最终服务运行效果却存在本质区别

根因排查方向

  • 构建环节差异校验
    • 逐包对比两个流水线产出的Jar包内容:检查BOOT-INF/classes路径下,自定义Jackson配置类、针对LocalDate的自定义序列化/反序列化类是否被完整打包,排除Gradle构建缓存差异导致的类遗漏问题——尤其要注意GitLab Runner用户下的本地Gradle缓存是否存在历史遗留的旧版本类文件,在增量构建时没有覆盖最新代码
    • 对比两个流程下的Gradle构建输出日志,确认自定义Jackson相关的配置类没有因为编译期注解处理、资源过滤规则的差异,被排除在最终Jar包外
  • 运行时加载差异校验
    • 检查GitLab Runner用户工作目录下的外部配置文件加载情况:确认是否存在因为目录权限问题,导致应用没有加载到预置的Jackson格式配置(比如spring.jackson.date-format、自定义序列化注册项)
    • 对比两个服务实例启动时的类加载顺序,确认是否存在类加载优先级偏移:比如GitLab Runner环境下,类加载器优先加载了Jackson内置的默认LocalDate反序列化实现,跳过了自定义的序列化逻辑注册
  • 隐性权限影响校验
    • 检查GitLab Runner运行上下文下,应用是否有权限读取Jar包内META-INF路径下的Jackson SPI扩展注册文件(比如Jackson2ObjectMapperBuilderCustomizer的SPI配置),排除权限不足导致的自定义扩展加载被跳过的问题

内容的提问来源于stack exchange,提问作者Inhwa Son

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.25 12:45:03