Spring Boot+Liquibase使用includeAll报错:无法确定文件路径
问题场景
Spring Boot 3.3.8 + Liquibase 4.27.0环境下,部署流水线从项目根目录/pipeline/dbscripts/liquibase读取脚本执行,本地开发时配置了Liquibase的变更日志路径:
spring: liquibase: enabled: true change-log: file:./pipeline/dbscripts/liquibase/db.changelog-master.yaml
当主变更日志使用includeAll引入子目录脚本时触发异常:
databaseChangeLog: - includeAll: path: ./changelog relativeToChangelogFile: true
异常信息如下(确认文件实际存在于对应路径):
Caused by: liquibase.exception.UnexpectedLiquibaseException: Could not determine path for
file:/home//IdeaProjects/project/pipeline/dbscripts/liquibase/changelog/2025/03/202503031455-create-table.yaml
但改用include指定单个脚本时,可正常运行:
databaseChangeLog: - include: file: ./changelog/2025/03/202503031455-create-table.yaml relativeToChangelogFile: true
问题原因
Liquibase 4.27.0在处理外部文件系统中的主变更日志(非classpath资源)时,includeAll的相对路径解析逻辑存在bug,无法正确基于主日志文件的位置递归识别子目录下的脚本文件;而include因为是直接指定单个文件路径,解析逻辑不受该bug影响。
解决方案
方案1:调整includeAll的路径配置
关闭relativeToChangelogFile,直接指定相对于项目根目录的完整路径:
databaseChangeLog: - includeAll: path: ./pipeline/dbscripts/liquibase/changelog relativeToChangelogFile: false
让Liquibase从项目根目录出发查找目标子目录,绕过相对路径解析的bug。
方案2:升级Liquibase版本
该路径解析bug在Liquibase 4.28.0及后续版本中已修复,升级依赖版本后可保留原includeAll配置不变。
方案3:临时使用include批量引入
如果暂时无法升级或调整路径,可继续使用include逐个引入脚本;若脚本数量较多,可借助构建工具(Maven/Gradle)的插件,在编译阶段自动生成包含所有脚本的主变更日志文件。
内容的提问来源于stack exchange,提问作者Shakirov Ramil

