使用Liquibase的Java应用无法定位指定文件夹问题求助
问题分析与解决方案
你的路径配置存在问题,核心原因在于**ClassLoaderResourceAccessor对相对路径的处理逻辑和你预期的不一样**,导致无法定位到目标文件夹。
为什么当前配置会失败?
你在db.changelog-master.xml里写的includeAll path="./../migrations/Test",是基于当前文件所在目录的相对路径(从db/changelog/master/向上一级到db/changelog/,再进入migrations/Test),这个路径在文件系统里是对的,但ClassLoaderResourceAccessor并不这么解析:
ClassLoaderResourceAccessor是通过JVM类加载器获取资源的,它所有的路径都是相对于classpath根目录(也就是你jar里的BOOT-INF/classes/),而不是相对于当前changelog文件的位置。- 你写的
./../migrations/Test会被类加载器解析为从classpath根向上跳一级(到BOOT-INF/目录),再找migrations/Test,这个路径显然不存在,所以会报错找不到文件夹。
解决办法
有两种可行的方案,你可以根据自己的项目情况选择:
方案1:改用classpath根的绝对路径
直接把includeAll的路径改成相对于classpath根的绝对路径,这样ClassLoaderResourceAccessor就能正确找到资源:
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.8.xsd" > <includeAll path="db/changelog/migrations/Test"/> </databaseChangeLog>
这个路径对应你jar里的BOOT-INF/classes/db/changelog/migrations/Test,完全匹配目标位置。
方案2:用Spring资源访问器(如果是Spring Boot项目)
如果你用的是Spring Boot,推荐使用SpringResourceAccessor替代ClassLoaderResourceAccessor,它能正确处理基于当前changelog文件的相对路径,不需要修改xml里的路径:
// 假设你在Spring环境中,可以注入ResourceLoader @Autowired private ResourceLoader resourceLoader; // 修改Liquibase初始化代码 Connection connection = openConnection(dbUrl, dbUsername, dbPassword); Database database = DatabaseFactory.getInstance().findCorrectDatabaseImplementation(new JdbcConnection(connection)); // 加载changelog资源 Resource changelogResource = resourceLoader.getResource("classpath:/db/changelog/master/db.changelog-master.xml"); // 使用SpringResourceAccessor Liquibase liquibase = new liquibase.Liquibase(changelogResource.getFilename(), new SpringResourceAccessor(changelogResource), database); logger.warn("LIQUIBASE:"+liquibase.toString()); liquibase.update(new Contexts("abc"));
这样你原来xml里的./../migrations/Test就能正常被解析,因为SpringResourceAccessor会基于当前changelog文件的位置计算相对路径。
内容的提问来源于stack exchange,提问作者Fabio
相关产品推荐
相关产品推荐

