Classpath prefix conflict between Gradle plugin and library

This post follows on from CORE-2766 which is marked for fix version 3.9.0. However that ticket is still open so I don’t believe the fix was ever merged.

I am trying to resolve a conflict between Liquibase as a library and as a Gradle plugin. Both sources use the same changelog files, but the file is accessed through a different path.

  1. The library includes the classpath prefix provided classpath:/db/changelog/master.xml
  2. The plugin uses the value /db/changelog/master.xml

This conflict means that the library does not recognise the changelog as the same file, and tries to re-run already executed scripts.
Mentioned in CORE-2766, the ignoreClasspathPrefix means that if the library runs first, subsequent runs by the plugin read classpath:db/changelog/init/1-0-table.mysql.sql from the DATABASECHANGELOG and strip the prefix to recognize the file has been run already. My issue is that after running an update through the plugin, the spring library fails because it tries to run the changes again under the classpath: path.

Are there any workarounds to this issue?
Where can I look to understand the Liquibase library better or develop a solution if this is a defect in liquibase?

The Liquibase gradle plugin is used to access Liquibase CLI through Gradle.
Relevant snippets from build.gradle

plugins {
    id 'org.liquibase.gradle' version '2.0.3'
}

project.ext {
    liquibaseVersion = '4.3.2'
    mysqlConnectorVersion = '8.0.19'
}

dependencies {
    implementation "org.liquibase:liquibase-core:$liquibaseVersion"
    implementation 'org.hibernate:hibernate-java8:5.4.10.Final'
    implementation 'org.springframework.boot:spring-boot-starter-web:2.2.4.RELEASE'
    implementation 'org.springframework.boot:spring-boot-starter-data-jpa:2.2.4.RELEASE'
    implementation 'org.springframework.boot:spring-boot-starter-security:2.2.4.RELEASE'

    liquibaseRuntime "org.liquibase:liquibase-core:$liquibaseVersion"
    liquibaseRuntime "mysql:mysql-connector-java:$mysqlConnectorVersion"
    liquibaseRuntime group: 'javax.xml.bind', name: 'jaxb-api', version: '2.3.1'
}

liquibase {
    activities {
        main {
            changeLogFile '/db/changelog/master.xml'
            classpath 'src/main/resources/'
            url  "${dbUrl}"
            username "${dbUser}"
            password "${dbPass}"
        }
    }
}

The Liquibase core library is used to automate changelog updates when the application is deployed.
Relevant snippets from build.gradle

project.ext {
    liquibaseVersion = '4.3.2'
}

dependencies {
    implementation "org.liquibase:liquibase-core:$liquibaseVersion"
    implementation 'org.springframework.boot:spring-boot-starter-web:2.2.4.RELEASE'
    implementation 'org.springframework.boot:spring-boot-starter-data-jpa:2.2.4.RELEASE'
    implementation 'org.springframework.boot:spring-boot-starter-security:2.2.4.RELEASE'
}

Relevant snippets from application.properties

spring.liquibase.change-log=classpath:/db/changelog/master.xml

Location of the files

./src
└── main
    ├── java
    └── resources
        ├── application.properties
        └── db
            └── changelog
                ├── init
                │   ├── 1-0-table.mysql.sql
                │   └── 1-0-view.mysql.sql
                └── master.xml

master.xml

<?xml version="1.0" encoding="UTF-8"?>   
<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">  

  <include  file="init/1-0-table.mysql.sql"
            relativeToChangelogFile="true" />

  <include  file="init/1-0-view.mysql.sql"
            relativeToChangelogFile="true"
            context="!test"/>

</databaseChangeLog>

WORKAROUND
After replacing a .xml master including mysql.sql files with a .yml master including .yml files, I have been able to run the updates without any conflict from the classpath.
New file structure:

./src
└── main
    ├── java
    └── resources
        ├── application.properties
        └── db
            └── changelog
                ├── init
                │   ├── 1-0-table.yml
                │   └── 1-0-view.yml
                └── master.yml

master.yml

databaseChangeLog:
  - include:
      file: init/1-0-table.yml
      relativeToChangelogFile: true
  - include:
      file: init/1-0-view.yml
      relativeToChangelogFile: true
      context: "!test"

Test scenarios on a new database

  1. Run spring project → DATABASECHANGELOG gets filename classpath:/db/changelog/init/1-0-table.yml → Run update from Gradle plugin → successfully skips update as there are no new files :white_check_mark:
  2. Run update from Gradle plugin → DATABASECHANGELOG adds filename /db/changelog/init/1-0-table.yml → Run spring project → successfully skips update as there are no new files :white_check_mark: