Upgrading from Liquibase 3.x to 4.x

I know it’s been a while since 4.0 has been released, but we still get questions about a common challenge with this upgrade.

If you see this error message, please read this post to know how to fix it.

Error Message

Specifying files by absolute path was removed in Liquibase 4.0. Please use a relative path or add ‘/’ to the classpath parameter.”

Background

When you reference a changelog file like /path/to/changelog.xml or path/to/changelog.xmlorchangelog.xml`, Liquibase has always looked for those by searching through all the directories and files in your “classpath”. It has never mattered whether you have a / at the beginning of your filename or not, the path you give is always looked for inside the entries in your classpath.

For example, if you have a classpath configured as:

  • /home/your-user
  • /liquibase/my-project
  • /liquibase/shared/files.zip

and a changelogFile of path/to/changelog.xml (or /path/to/changelog.xml`)

then, Liquibase will look for that changelog file as:

  • /home/your-user/path/to/changelog.xml
  • /liquibase/my-project/path/to/changelog.xml
  • inside /liquibase/shared/files.zip for an entry named path/to/changelog.xml

Exactly what is in your configured classpath is made up of two things:

  1. What you list in your classpath argument/liquibase.properties setting/etc.
  2. A default list of “normal” locations that the CLI/Maven/Ant/etc. interfaces know users normally expect to look for files in.

What Changed in 4.0

Prior to 4.0, one of the default classpath entries that the CLI used was your filesystem root directory. We removed that in 4.0 for several reasons.

Partly it was because it harmed performance, since includeAll path="/" would search your entire filesystem.

But also because the the reason for the “look up changelog files relative to the classpath entries” logic exists to avoid machine-specific paths. Liquibase uses the path to the changelog file as part of each changeset’s unique identifier and so that needs to remain consistent, even if your project gets moved to a different directory on the same machine or ran from another machine. To keep those paths consistent, you really want to have the classpath entry be the “machine dependent” part so that the path to the changelog file is always consistent.

By having the root of your filesystem as a default classpath entry, it was too easy for new users to just reference their changelog files with machine-dependent “absolute” paths. That works fine at first, but at some point will burn them and we want to avoid that.

Adjusting to the Change

If you are already using changelog paths relative to a classpath entry besides the root directory, there is no change you need to make. If you are seeing the “Specifying files by absolute path was removed in Liquibase 4.0.” message, it is just because the path isn’t being found as you are expecting.

If you had been trying to reference the file relative to the root directory, you have two options:

  1. Add / to your classpath setting. This brings back the old behavior with both the possible performance issue to watch for and the possible machine-dependent issues. But, if those are not a problem for you this is an easy solution.
  2. Correctly configure your classpath and update your changelogFile references to be relative to those classpath entries. Because your ran changesets will be stored with the complete path from before, you’ll need to add logicalFilePath to the changelog files to override the path portion of the changeset identifier.

Nathan

1 Like

Hi @nvoxland, Thank you for posting the suggestion! :slight_smile: