1
2
3
databaseChangeLog:
- includeAll:
path: classpath*:/changelogs
June 13, 2019
Update December 2020
The Liquibase PR 1140 has been merged into 3.10.x branch. Starting with 2.3.7, the new version is also integrated into Spring Boot - everything should now work as expected!
If you would like to initialize a Spring Boot project with custom database schema, multi-module option and Liquibase scripts, check out Bootify.io - create your first prototype in no time.
Backgrounds
IncludeAll should detect all changelog files matching the given pattern, for example:
However, when the changelogs are distributed over several modules as part of a Spring Boot fat jar, not all of them are picked up.
This issue has been discussed already, but is still not fixed (Liquibase 3.6.3). It looks like it’s coming from the line getResources("")
, which is supposed to find the root path of every jar file in the project, but is incomplete when running in a fat jar. So instead one could try to get the base paths with another resource lookup, searching for all xml and yaml files in the project. As every relevant jar contains a changelog file with such an ending, the list should be complete.
Workaround
Until a proper bugfix is released, I suggest the following workaround.
-
Create a copy of
SpringLiquibase.java
contained in the Liquibase library you are working with. Keep exactly the same package (liquibase.integration.spring
), so this class will take precedence over the original one when being picked up by the classloader. -
Add the following snippet into the
SpringResourceOpener
class. Call the new method as part ofcreateResourceOpener()
.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public void addSpringBootJars(ResourceLoader resourceLoader) {
ResourcePatternResolver resolver = ResourcePatternUtils.getResourcePatternResolver(resourceLoader);
for (String ending : new String[] {"xml", "yml", "yaml"}) {
Resource[] resources = resolver.getResources("classpath*:**/*." + ending);
for (Resource resource : resources) {
String url = resource.getURL().toExternalForm();
if (!url.startsWith("jar:")) {
continue;
}
url = url.substring(4, url.indexOf('!'));
url = url.replace("\\", "/");
if (url.startsWith("file:") && url.charAt(5) != '/') {
url = "file:/" + url.substring(5) + "/";
}
if (!getRootPaths().contains(url)) {
addRootPath(new URL(url));
}
}
}
}
Now all relevant jars of your Spring Boot project should be found - containing a changelog file ending with xml, yml or yaml! Let me know if you have any further suggestions.