我有一个与Liquibase集成的多模块Spring Boot应用程序。从IDE中运行时,liquibase脚本可以正常工作。但是,从罐子中运行时,他们却没有。经过一番调查,似乎在尝试从嵌入式jar读取时,liquibase本身存在重大问题。 liquibase脚本本身位于胖罐内的嵌入式罐中,并且主xml文件如下所示:
<includeAll path="classpath*:config/liquibase/changelog/"/>
经过进一步调查,我将所有内容缩小到liquibase本身内部的问题。我使用的版本是liquibase-3.6.2。我怀疑在liquibase中存在的错误在以下类别中: liquibase.resource.ClassLoaderResourceAccessor 我缩小范围的方法是
public Set<String> list(String relativeTo, String path, boolean includeFiles, boolean includeDirectories, boolean recursive) throws IOException
此方法的输入如下:
relativeTo = null
path = jar:file:/C:/#{SOME_PATH}/xxx-1.0.0.0-SNAPSHOT.jar!/BOOT-INF/lib/yyy-1.0.0.0-SNAPSHOT.jar!/config/liquibase/changelog/
includeFiles = true
includeDirectories = false
recursive = true
当然,您需要将#{SOME_PATH}替换为磁盘上的有效路径。我出于安全目的对其进行了编辑。我们已经注意到liquibase发现在胖罐xxx内的嵌入式yyy罐内可能有一些脚本。
此方法的问题在于,它不返回jar内的XML脚本,而是返回yyy jar本身。这只会在稍后的代码中导致错误,因此我假定查找XML文件是该方法的责任(因为如果我直接从IDE而不是从jar中运行项目,则可以成功找到XML文件)。
我注意到的主要问题所在的行是第134行:
String returnPath = SpringBootFatJar.getSimplePathForResources(entry.getName(), path);
这时,路径变量已损坏,SpringBootFatJar返回了损坏的返回路径。在以下部分中,我将描述发生的情况:
不幸的是,我本周没有时间对此做进一步的调查,我想将这个问题发布到stackoverflow上,以查看是否还有其他人有这个问题,这是否是已知的liquibase错误,以及是否有简单的解决方法它。我将在下周尝试进一步研究它,并检查所有这些问题是否从第105行看似差的路径参数中级联,因为输入的路径参数中有两个“!/”实例。
谢谢
答案 0 :(得分:0)
万一有人偶然发现了这个问题,他们将其固定在master上,但尚未发布。我们所做的就是从github那里获得他们的主人,并从中编译了一个SNAPSHOT。撰写本文时,结果是3.7.0-SNAPSHOT。到达后,我们将使用3.7.0官方版本。
答案 1 :(得分:0)
显然,它仍然不能与当前的liquibase版本(3.8.5)一起使用。不会从Spring Boot胖子罐中的其他罐子中获取Changelog。 一种解决方法是覆盖SpringLiquibase.java文件并手动更新jar列表。有关详细信息,请参见:http://www.it-surmann.com/spring-boot/fix-liquibase-includeall-in-a-spring-boot-project_1002.html