Search code examples
javaspringliquibase

Running Liquibase with Custom Change


Currently I'm experimenting with Liquibase and trying to run a customChange. The Project is Spring-Webflux based, compiled into a fat jar. Every time I try to run the Liquibase with the customChange I've created, I ran into

[ERROR] Error setting up or running Liquibase:
[ERROR] liquibase.exception.ChangeLogParseException: liquibase.parser.core.ParsedNodeException: liquibase.exception.CustomChangeException: java.lang.ClassNotFoundException: com.abl.rjmdb.liquibase.DoNothingChange

DoNothingChange:

package com.abl.rjmdb.liquibase;

import liquibase.change.AbstractChange;
import liquibase.database.Database;
import liquibase.statement.SqlStatement;

public class DoNothingChange extends AbstractChange {
    public String getConfirmationMessage() {
        return "OK";
    }

    public SqlStatement[] generateStatements(Database database) {
        return new SqlStatement[0];
    }
}

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>3.2.5</version>
    <relativePath/>
    <!-- lookup parent from repository -->
  </parent>
  <groupId>com.abl</groupId>
  <artifactId>rjmdb</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <name>rjmdb</name>
  <description>Reactive Movie Database</description>

  <properties>
    <java.version></java.version>
    <jooq.version>3.19.8</jooq.version>
    <r2dbc-postgresql.version>1.0.5.RELEASE</r2dbc-postgresql.version>
    <postgresql.version>42.7.3</postgresql.version>
    <modelmapper-jooq.version>3.2.0</modelmapper-jooq.version>
    <springdoc-openapi-starter-webflux-ui.version>2.4.0</springdoc-openapi-starter-webflux-ui.version>
    <spring-cloud-config-client.version>4.1.1</spring-cloud-config-client.version>
    <jooq-meta-extensions-liquibase.version>3.19.9</jooq-meta-extensions-liquibase.version>
    <liquibase-maven-plugin.version>4.28.0</liquibase-maven-plugin.version>
    <liquibase-core.version>4.28.0</liquibase-core.version>
    <maven-compiler-plugin.target>17</maven-compiler-plugin.target>
    <maven-compiler-plugin.source>17</maven-compiler-plugin.source>
  </properties>

  <dependencies>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-webflux</artifactId>
    </dependency>
    <dependency>
      <groupId>org.projectlombok</groupId>
      <artifactId>lombok</artifactId>
      <optional>true</optional>
    </dependency>
    <dependency>
      <groupId>org.jooq</groupId>
      <artifactId>jooq</artifactId>
      <version>${jooq.version}</version>
    </dependency>
    <dependency>
      <groupId>org.jooq</groupId>
      <artifactId>jooq-meta</artifactId>
      <version>${jooq.version}</version>
    </dependency>
    <dependency>
      <groupId>org.jooq</groupId>
      <artifactId>jooq-codegen</artifactId>
      <version>${jooq.version}</version>
    </dependency>
    <dependency>
      <groupId>org.postgresql</groupId>
      <artifactId>postgresql</artifactId>
      <version>${postgresql.version}</version>
    </dependency>
    <dependency>
      <groupId>org.postgresql</groupId>
      <artifactId>r2dbc-postgresql</artifactId>
      <version>${r2dbc-postgresql.version}</version>
    </dependency>
    <dependency>
      <groupId>org.modelmapper.extensions</groupId>
      <artifactId>modelmapper-jooq</artifactId>
      <version>${modelmapper-jooq.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springdoc</groupId>
      <artifactId>springdoc-openapi-starter-webflux-ui</artifactId>
      <version>${springdoc-openapi-starter-webflux-ui.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-config-client</artifactId>
      <version>${spring-cloud-config-client.version}</version>
    </dependency>
    <dependency>
      <groupId>org.liquibase</groupId>
      <artifactId>liquibase-core</artifactId>
      <version>${liquibase-core.version}</version>
    </dependency>
    <dependency>
      <groupId>org.jooq</groupId>
      <artifactId>jooq-meta-extensions-liquibase</artifactId>
      <version>3.19.9</version>
    </dependency>

    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-test</artifactId>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>io.projectreactor</groupId>
      <artifactId>reactor-test</artifactId>
      <scope>test</scope>
    </dependency>
  </dependencies>

  <profiles>
    <profile>
      <id>local</id>
      <properties>
        <database.url>jdbc:postgresql://localhost:5432/db</database.url>
        <database.user>user</database.user>
        <database.password>password</database.password>
        <database.schema>public</database.schema>
      </properties>
      <build>
        <plugins>
          <plugin>
            <groupId>org.liquibase</groupId>
            <artifactId>liquibase-maven-plugin</artifactId>
            <version>${liquibase-maven-plugin.version}</version>
            <executions>
              <execution>
                <phase>generate-resources</phase>
                <goals>
                  <goal>update</goal>
                </goals>
              </execution>
            </executions>
            <dependencies>
              <dependency>
                <groupId>org.postgresql</groupId>
                <artifactId>postgresql</artifactId>
                <version>${postgresql.version}</version>
              </dependency>
            </dependencies>
            <configuration>
              <changeSetPath></changeSetPath>
              <searchPath>${basedir}</searchPath>
              <changeLogFile>src/main/resources/changelog-db.xml</changeLogFile>
              <driver>org.postgresql.Driver</driver>
              <url>${database.url}</url>
              <username>${database.user}</username>
              <password>${database.password}</password>
            </configuration>
          </plugin>

          <plugin>
            <groupId>org.jooq</groupId>
            <artifactId>jooq-codegen-maven</artifactId>
            <version>${jooq.version}</version>

            <executions>
              <execution>
                <phase>generate-sources</phase>
                <goals>
                  <goal>generate</goal>
                </goals>
              </execution>
            </executions>

            <configuration>
              <jdbc>
                <url>${database.url}</url>
                <user>${database.user}</user>
                <password>${database.password}</password>
              </jdbc>
              <generator>
                <database>
                  <includes>.*</includes>
                  <inputSchema>${database.schema}</inputSchema>
                </database>
                <target>
                  <packageName>com.abl.rjmdb.model.jooq</packageName>
                  <directory>${project.build.directory}/generated-sources/jooq</directory>
                </target>
              </generator>
            </configuration>
          </plugin>
        </plugins>
      </build>
    </profile>
  </profiles>


  <build>
    <plugins>
      <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
        <configuration>
          <excludes>
            <exclude>
              <groupId>org.projectlombok</groupId>
              <artifactId>lombok</artifactId>
            </exclude>
          </excludes>
        </configuration>
      </plugin>
    </plugins>
  </build>
</project>

Changelog file -

<?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-4.28.xsd">

  <changeSet id="1" author="liquibase">
    <createTable tableName="department">
      <column name="id" type="int">
        <constraints primaryKey="true" />
      </column>
      <column name="dept" type="varchar(70)">
        <constraints nullable="false" />
      </column>
      <column name="emp_id" type="int">
        <constraints nullable="false" />
      </column>
    </createTable>
  </changeSet>

  <changeSet id="2" author="a">
    <customChange class="com.abl.rjmdb.liquibase.DoNothingChange" />
  </changeSet>

</databaseChangeLog>

And here's the file system structure -

RJMDB  D:\Programming Projects\RJMDB
  .idea
  .mvn
  src
    main
      java
        com.abl.rjmdb
          configuration
          controller
          liquibase
            DoNothingChange
          model
          persistance
          service
          RjmdbApplication
      resources
        application.yml
        application-local.yml
        changelog-db.xml
    test
  target
  .gitignore
  Dockerfile
  HELP.md
  init.sql
  mvnw
  mvnw.cmd
  pom.xml
  README.md
  rjmdb.iml

I try to run the Liquibase with - mvn clean install -Plocal and it works fine as far as I don't use any custom change. I've been told to export the custom changes to a different jar but it feels like it contradicts the entire far jar philosophy.


Solution

  • I managed to run custom changes by creating a module (jar) of the custom changes and then use it as a dependency in the maven-liquibase-plugin.

        <profiles>
        <profile>
            <id>local</id>
            <properties>
                <database.url>jdbc:postgresql://localhost:5432/db</database.url>
                <database.user>user</database.user>
                <database.password>password</database.password>
                <database.schema>public</database.schema>
            </properties>
            <build>
                <plugins>
                    <plugin>
                        <groupId>org.liquibase</groupId>
                        <artifactId>liquibase-maven-plugin</artifactId>
                        <version>${liquibase-maven-plugin.version}</version>
                        <executions>
                            <execution>
                                <phase>generate-resources</phase>
                                <goals>
                                    <goal>update</goal>
                                </goals>
                            </execution>
                        </executions>
                        <dependencies>
                            <dependency>
                                <groupId>com.abl.rjmdb</groupId>
                                <artifactId>liquibase</artifactId>
                                <version>1.0-SNAPSHOT</version>
                            </dependency>
                            <dependency>
                                <groupId>org.postgresql</groupId>
                                <artifactId>postgresql</artifactId>
                                <version>${postgresql.version}</version>
                            </dependency>
                        </dependencies>
                        <configuration>
                            <searchPath>${basedir}/src/main/resources</searchPath>
                            <propertyFile>liquibase.properties</propertyFile>
                        </configuration>
                    </plugin>
                </plugins>
            </build>
        </profile>
    </profiles>
    

    A much more detailed reference can be used with this repository