relativeToChangeLogFile not working as documented

The manual describes the option relativeToChangeLogFile for the sqlFile tag as:

Indicates whether the file path is relative to the root changelog

However Liquibase 4.3.3 takes this as “relative to the current directory”.

My setup is like this:

I have the following directory structure:

 MyProject
    changelog\
       views\
          view_1.sql
       main.xml
       views.xml

`views.xml` is included from `main.xml` and contains this changeSet:

<changeSet author="...." id="1" runOnChange="true">
  <sqlFile path="views/view_1.sql" 
       encoding="UTF-8"
       relativeToChangelogFile="true" 
       stripComments="false" 
       splitStatements="true" endDelimiter=";" /> 
</changeSet>

I run Liquibase from the parent directory of changelog, e.g.

c:\MyProject> liquibase --changeLogFile=changelog\main.xml ....

This worked fine with Liquibase 2.x and 3.x but in Liquibase 4.3.3 it fails with the following confusing error message:

Unexpected error running Liquibase: java.io.IOException: The file views/view_1.sql was not found in
    - c:\MyProject\.
    - c:\MyProject\postgresql-42.2.18.jar
Specifying files by absolute path was removed in Liquibase 4.0. Please use a relative path or add '/' to the classpath parameter.

So Liquibase apparently searches the file relative to the current directory, not relative to the master change log file as stated in the manual.

The error message is also confusing as I am not using an absolute file path, but a relative one.

Is there any way to get the 3.x behaviour back? Should I report this as a bug?

I’m seriously considering going back to 3.x because of this. This breaks many projects, and we can’t afford to modify all changelogs because of that - which wouldn’t really help anyway as the “current directory” might be different depending on the environment where this is run (manually, Maven, Jenkins, etc)

Note that <include ... relativeToChangelogFile="true"/> works as expected - so there is a difference in the processing of this attribute between <include> and <sqlFile>. Which makes be think this is a bug even more.

The stacktrace might be interesting as it does not even mention the SQLFileChange class. So this seems to fail before the tag gets to see the file name:

    at liquibase.changelog.ChangeLogIterator.run(ChangeLogIterator.java:124)
    at liquibase.changelog.DatabaseChangeLog.validate(DatabaseChangeLog.java:292)
    at liquibase.Liquibase.lambda$update$1(Liquibase.java:237)
    at liquibase.Scope.lambda$child$0(Scope.java:160)
    at liquibase.Scope.child(Scope.java:169)
    at liquibase.Scope.child(Scope.java:159)
    at liquibase.Scope.child(Scope.java:138)
    at liquibase.Liquibase.runInScope(Liquibase.java:2369)
    at liquibase.Liquibase.update(Liquibase.java:217)
    at liquibase.Liquibase.update(Liquibase.java:203)
    at liquibase.integration.commandline.Main.doMigration(Main.java:1802)
    at liquibase.integration.commandline.Main$1.lambda$run$0(Main.java:367)
    at liquibase.Scope.lambda$child$0(Scope.java:160)
    at liquibase.Scope.child(Scope.java:169)
    at liquibase.Scope.child(Scope.java:159)
    at liquibase.Scope.child(Scope.java:138)
    at liquibase.integration.commandline.Main$1.run(Main.java:366)
    at liquibase.integration.commandline.Main$1.run(Main.java:196)
    at liquibase.Scope.child(Scope.java:169)
    at liquibase.Scope.child(Scope.java:145)
    at liquibase.integration.commandline.Main.run(Main.java:196)
    at liquibase.integration.commandline.Main.main(Main.java:158)
1 Like

Hi @truls , since you have a reproducible case, I would file an issue.