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

升级Liquibase版本后类路径部分文件无法找到的问题排查

Liquibase 4.24.0 全新数据库初始化时无法读取Fat Jar中的子变更日志文件

问题现象

  • 用Testcontainer搭建备份数据库,通过Shell调用Liquibase CLI执行update做初始化,主变更日志能在Fat Jar中找到,但它引用的子变更文件(写法为<include file="dbs/X/v1.0/X.xml"/>)被Liquibase强制在本地目录查找,报错日志:

    [2023-11-02 21:02:56] FINE [liquibase.resource] Path dbs/X/X/increments/X.xml in does not exist (liquibase.resource.DirectoryResourceAccessor ())

  • 这些子文件实际存在于Fat Jar内部
  • 版本相关触发条件:
    • 回退到Liquibase 4.9.1可正常运行
    • 已有数据的数据库用4.24.0执行update无异常,仅全新数据库初始化时触发问题
  • 当前临时 workaround:放弃新版本的labels功能,改用contexts过滤变更集

问题原因

Liquibase 4.24.0在全新数据库初始化流程中修改了资源访问逻辑:当数据库中不存在Liquibase元数据表(如databasechangelog)时,会优先使用DirectoryResourceAccessor读取本地目录,而非从主变更日志所在的类路径(Fat Jar)加载子文件。旧版本(如4.9.1)则会始终从主变更日志的资源路径解析引用的子文件。

解决办法

1. 显式指定类路径资源访问器

执行Liquibase命令时,强制指定使用ClasspathResourceAccessor,让Liquibase从类路径加载所有变更文件:

liquibase --changeLogFile=classpath:/your/main/changelog.xml --resource-accessor=liquibase.resource.ClasspathResourceAccessor update

将/your/main/changelog.xml替换为Fat Jar中主变更日志的实际类路径。

2. 修改子变更日志的引用路径

把<include>标签内的路径改为类路径绝对格式,明确告知Liquibase从类路径加载:

<include file="classpath:/dbs/X/v1.0/X.xml"/>

这种方式无需修改CLI命令,直接调整变更日志文件即可。

3. 先初始化元数据表再执行更新

利用"已有元数据表时4.24.0可正常工作"的特性,先手动同步变更日志初始化元数据表,再执行更新:

  1. 先执行:
    liquibase changelog-sync
    
  2. 再执行:
    liquibase update
    

以此绕过全新数据库时的资源访问逻辑问题。

验证要点

  • 测试时确保Testcontainer启动的是完全干净的数据库(无Liquibase元数据表)
  • 确认Fat Jar已正确打包所有变更日志文件,类路径配置无误

内容的提问来源于stack exchange,提问作者Martin Mucha

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 10:01:00