Trying to use customChange changeset, I get java.lang.ClassNotFoundException

Hi everyone,

So I would like to make some tests with customChange.

I have implemented same class as in the example here customChange, but with different name:

package liquibase.change.custom;

import liquibase.Scope;
import liquibase.database.Database;
import liquibase.exception.CustomChangeException;
import liquibase.exception.RollbackImpossibleException;
import liquibase.exception.SetupException;
import liquibase.exception.ValidationErrors;
import liquibase.resource.ResourceAccessor;

public class RollbackRerunableCustomTaskChange implements CustomTaskChange, CustomTaskRollback {

    private String helloTo;

    @SuppressWarnings({"UnusedDeclaration", "FieldCanBeLocal"})
    private ResourceAccessor resourceAccessor;


    public String getHelloTo() {
        return helloTo;
    }

    public void setHelloTo(String helloTo) {
        this.helloTo = helloTo;
    }

    @Override
    public void execute(Database database) throws CustomChangeException {
        Scope.getCurrentScope().getLog(getClass()).info("Hello "+getHelloTo());
    }

    @Override
    public void rollback(Database database) throws CustomChangeException, RollbackImpossibleException {
        Scope.getCurrentScope().getLog(getClass()).info("Goodbye "+getHelloTo());
    }

    @Override
    public String getConfirmationMessage() {
        return "Said Hello";
    }

    @Override
    public void setUp() throws SetupException {
        ;
    }

    @Override
    public void setFileOpener(ResourceAccessor resourceAccessor) {
        this.resourceAccessor = resourceAccessor;
    }

    @Override
    public ValidationErrors validate(Database database) {
        return new ValidationErrors();
    }
}

I built the liquibase-core project and taken my custom .class. I packaged it using:

jar cf RollbackRerunableCustomTaskChange.jar .\RollbackRerunableCustomTaskChange.class

I copied .jar file into global lib folder, so I think it should be automatically loaded. Also tryed in a local lib folder and referencing to in as this:
classpath: ./lib/mssql-jdbc-11.2.0.jre18.jar;./lib/RollbackRerunableCustomTaskchange.jar in properties file

My changeset looks like this:

<changeSet id="21" author="bla">
	<customChange class="liquibase.change.custom.RollbackRerunableCustomTaskChange">
		<param name="helloTo" value="world"/>
	</customChange>
</changeSet>

And the error I get:

[2022-11-24 12:50:18] SEVERE [liquibase.integration] liquibase.change.custom.RollbackRerunableCustomTaskChange
liquibase.exception.CommandExecutionException: liquibase.exception.ChangeLogParseException: liquibase.exception.SetupException: liquibase.parser.core.ParsedNodeException: liquibase.exception.CustomChangeException: java.lang.ClassNotFoundException: liquibase.change.custom.RollbackRerunableCustomTaskChange
        at liquibase.command.CommandScope.execute(CommandScope.java:179)
        at liquibase.integration.commandline.CommandRunner.call(CommandRunner.java:54)
        at liquibase.integration.commandline.CommandRunner.call(CommandRunner.java:23)
        at picocli.CommandLine.executeUserObject(CommandLine.java:1953)
        at picocli.CommandLine.access$1300(CommandLine.java:145)
        at picocli.CommandLine$RunLast.executeUserObjectOfLastSubcommandWithSameParent(CommandLine.java:2358)
        at picocli.CommandLine$RunLast.handle(CommandLine.java:2352)
        at picocli.CommandLine$RunLast.handle(CommandLine.java:2314)
        at picocli.CommandLine$AbstractParseResultHandler.execute(CommandLine.java:2179)
        at picocli.CommandLine$RunLast.execute(CommandLine.java:2316)
        at picocli.CommandLine.execute(CommandLine.java:2078)
        at liquibase.integration.commandline.LiquibaseCommandLine.lambda$execute$1(LiquibaseCommandLine.java:353)
        at liquibase.Scope.child(Scope.java:189)
        at liquibase.Scope.child(Scope.java:165)
        at liquibase.integration.commandline.LiquibaseCommandLine.execute(LiquibaseCommandLine.java:318)
        at liquibase.integration.commandline.LiquibaseCommandLine.main(LiquibaseCommandLine.java:84)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.base/java.lang.reflect.Method.invoke(Method.java:566)
        at liquibase.integration.commandline.LiquibaseLauncher.main(LiquibaseLauncher.java:107)
Caused by: liquibase.exception.ChangeLogParseException: liquibase.exception.SetupException: liquibase.parser.core.ParsedNodeException: liquibase.exception.CustomChangeException: java.lang.ClassNotFoundException: liquibase.change.custom.RollbackRerunableCustomTaskChange
        at liquibase.parser.core.xml.AbstractChangeLogParser.parse(AbstractChangeLogParser.java:25)
        at liquibase.Liquibase.getDatabaseChangeLog(Liquibase.java:408)
        at liquibase.Liquibase.getDatabaseChangeLog(Liquibase.java:393)
        at liquibase.Liquibase.lambda$update$1(Liquibase.java:249)
        at liquibase.Scope.lambda$child$0(Scope.java:180)
        at liquibase.Scope.child(Scope.java:189)
        at liquibase.Scope.child(Scope.java:179)
        at liquibase.Scope.child(Scope.java:158)
        at liquibase.Liquibase.runInScope(Liquibase.java:2447)
        at liquibase.Liquibase.update(Liquibase.java:236)
        at liquibase.Liquibase.update(Liquibase.java:221)
        at liquibase.integration.commandline.Main.doMigration(Main.java:1829)
        at liquibase.integration.commandline.Main$1.lambda$run$0(Main.java:394)
        at liquibase.Scope.lambda$child$0(Scope.java:180)
        at liquibase.Scope.child(Scope.java:189)
        at liquibase.Scope.child(Scope.java:179)
        at liquibase.Scope.child(Scope.java:158)
        at liquibase.integration.commandline.Main$1.run(Main.java:393)
        at liquibase.integration.commandline.Main$1.run(Main.java:215)
        at liquibase.Scope.child(Scope.java:189)
        at liquibase.Scope.child(Scope.java:165)
        at liquibase.integration.commandline.Main.run(Main.java:215)
        at liquibase.command.AbstractCliWrapperCommandStep.run(AbstractCliWrapperCommandStep.java:33)
        at liquibase.command.CommandScope.execute(CommandScope.java:173)
        ... 20 more
Caused by: liquibase.exception.SetupException: liquibase.parser.core.ParsedNodeException: liquibase.exception.CustomChangeException: java.lang.ClassNotFoundException: liquibase.change.custom.RollbackRerunableCustomTaskChange
        at liquibase.changelog.DatabaseChangeLog.handleChildNode(DatabaseChangeLog.java:419)
        at liquibase.changelog.DatabaseChangeLog.load(DatabaseChangeLog.java:364)
        at liquibase.parser.core.xml.AbstractChangeLogParser.parse(AbstractChangeLogParser.java:23)
        ... 43 more
Caused by: liquibase.exception.ChangeLogParseException: liquibase.parser.core.ParsedNodeException: liquibase.exception.CustomChangeException: java.lang.ClassNotFoundException: liquibase.change.custom.RollbackRerunableCustomTaskChange
        at liquibase.parser.core.xml.AbstractChangeLogParser.parse(AbstractChangeLogParser.java:25)
        at liquibase.changelog.DatabaseChangeLog.include(DatabaseChangeLog.java:717)
        at liquibase.changelog.DatabaseChangeLog.handleChildNode(DatabaseChangeLog.java:411)
        ... 45 more
Caused by: liquibase.parser.core.ParsedNodeException: liquibase.exception.CustomChangeException: java.lang.ClassNotFoundException: liquibase.change.custom.RollbackRerunableCustomTaskChange
        at liquibase.change.custom.CustomChangeWrapper.load(CustomChangeWrapper.java:300)
        at liquibase.changelog.ChangeSet.toChange(ChangeSet.java:535)
        at liquibase.changelog.ChangeSet.handleChildNode(ChangeSet.java:460)
        at liquibase.changelog.ChangeSet.load(ChangeSet.java:384)
        at liquibase.changelog.DatabaseChangeLog.createChangeSet(DatabaseChangeLog.java:761)
        at liquibase.changelog.DatabaseChangeLog.handleChildNode(DatabaseChangeLog.java:395)
        at liquibase.changelog.DatabaseChangeLog.load(DatabaseChangeLog.java:364)
        at liquibase.parser.core.xml.AbstractChangeLogParser.parse(AbstractChangeLogParser.java:23)
        ... 47 more
Caused by: liquibase.exception.CustomChangeException: java.lang.ClassNotFoundException: liquibase.change.custom.RollbackRerunableCustomTaskChange
        at liquibase.change.custom.CustomChangeWrapper.setClass(CustomChangeWrapper.java:89)
        at liquibase.change.custom.CustomChangeWrapper.load(CustomChangeWrapper.java:298)
        ... 54 more
Caused by: java.lang.ClassNotFoundException: liquibase.change.custom.RollbackRerunableCustomTaskChange
        at java.base/java.net.URLClassLoader.findClass(URLClassLoader.java:471)
        at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:588)
        at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
        at java.base/java.lang.Class.forName0(Native Method)
        at java.base/java.lang.Class.forName(Class.java:398)
        at liquibase.change.custom.CustomChangeWrapper.setClass(CustomChangeWrapper.java:79)
        ... 55 more


Unexpected error running Liquibase: liquibase.change.custom.RollbackRerunableCustomTaskChange

liquibase.exception.CommandExecutionException: liquibase.exception.ChangeLogParseException: liquibase.exception.SetupException: liquibase.parser.core.ParsedNodeException: liquibase.exception.CustomChangeException: java.lang.ClassNotFoundException: liquibase.change.custom.RollbackRerunableCustomTaskChange
        at liquibase.command.CommandScope.execute(CommandScope.java:179)
        at liquibase.integration.commandline.CommandRunner.call(CommandRunner.java:54)
        at liquibase.integration.commandline.CommandRunner.call(CommandRunner.java:23)
        at picocli.CommandLine.executeUserObject(CommandLine.java:1953)
        at picocli.CommandLine.access$1300(CommandLine.java:145)
        at picocli.CommandLine$RunLast.executeUserObjectOfLastSubcommandWithSameParent(CommandLine.java:2358)
        at picocli.CommandLine$RunLast.handle(CommandLine.java:2352)
        at picocli.CommandLine$RunLast.handle(CommandLine.java:2314)
        at picocli.CommandLine$AbstractParseResultHandler.execute(CommandLine.java:2179)
        at picocli.CommandLine$RunLast.execute(CommandLine.java:2316)
        at picocli.CommandLine.execute(CommandLine.java:2078)
        at liquibase.integration.commandline.LiquibaseCommandLine.lambda$execute$1(LiquibaseCommandLine.java:353)
        at liquibase.Scope.child(Scope.java:189)
        at liquibase.Scope.child(Scope.java:165)
        at liquibase.integration.commandline.LiquibaseCommandLine.execute(LiquibaseCommandLine.java:318)
        at liquibase.integration.commandline.LiquibaseCommandLine.main(LiquibaseCommandLine.java:84)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.base/java.lang.reflect.Method.invoke(Method.java:566)
        at liquibase.integration.commandline.LiquibaseLauncher.main(LiquibaseLauncher.java:107)
Caused by: liquibase.exception.ChangeLogParseException: liquibase.exception.SetupException: liquibase.parser.core.ParsedNodeException: liquibase.exception.CustomChangeException: java.lang.ClassNotFoundException: liquibase.change.custom.RollbackRerunableCustomTaskChange
        at liquibase.parser.core.xml.AbstractChangeLogParser.parse(AbstractChangeLogParser.java:25)
        at liquibase.Liquibase.getDatabaseChangeLog(Liquibase.java:408)
        at liquibase.Liquibase.getDatabaseChangeLog(Liquibase.java:393)
        at liquibase.Liquibase.lambda$update$1(Liquibase.java:249)
        at liquibase.Scope.lambda$child$0(Scope.java:180)
        at liquibase.Scope.child(Scope.java:189)
        at liquibase.Scope.child(Scope.java:179)
        at liquibase.Scope.child(Scope.java:158)
        at liquibase.Liquibase.runInScope(Liquibase.java:2447)
        at liquibase.Liquibase.update(Liquibase.java:236)
        at liquibase.Liquibase.update(Liquibase.java:221)
        at liquibase.integration.commandline.Main.doMigration(Main.java:1829)
        at liquibase.integration.commandline.Main$1.lambda$run$0(Main.java:394)
        at liquibase.Scope.lambda$child$0(Scope.java:180)
        at liquibase.Scope.child(Scope.java:189)
        at liquibase.Scope.child(Scope.java:179)
        at liquibase.Scope.child(Scope.java:158)
        at liquibase.integration.commandline.Main$1.run(Main.java:393)
        at liquibase.integration.commandline.Main$1.run(Main.java:215)
        at liquibase.Scope.child(Scope.java:189)
        at liquibase.Scope.child(Scope.java:165)
        at liquibase.integration.commandline.Main.run(Main.java:215)
        at liquibase.command.AbstractCliWrapperCommandStep.run(AbstractCliWrapperCommandStep.java:33)
        at liquibase.command.CommandScope.execute(CommandScope.java:173)
        ... 20 more
Caused by: liquibase.exception.SetupException: liquibase.parser.core.ParsedNodeException: liquibase.exception.CustomChangeException: java.lang.ClassNotFoundException: liquibase.change.custom.RollbackRerunableCustomTaskChange
        at liquibase.changelog.DatabaseChangeLog.handleChildNode(DatabaseChangeLog.java:419)
        at liquibase.changelog.DatabaseChangeLog.load(DatabaseChangeLog.java:364)
        at liquibase.parser.core.xml.AbstractChangeLogParser.parse(AbstractChangeLogParser.java:23)
        ... 43 more
Caused by: liquibase.exception.ChangeLogParseException: liquibase.parser.core.ParsedNodeException: liquibase.exception.CustomChangeException: java.lang.ClassNotFoundException: liquibase.change.custom.RollbackRerunableCustomTaskChange
        at liquibase.parser.core.xml.AbstractChangeLogParser.parse(AbstractChangeLogParser.java:25)
        at liquibase.changelog.DatabaseChangeLog.include(DatabaseChangeLog.java:717)
        at liquibase.changelog.DatabaseChangeLog.handleChildNode(DatabaseChangeLog.java:411)
        ... 45 more
Caused by: liquibase.parser.core.ParsedNodeException: liquibase.exception.CustomChangeException: java.lang.ClassNotFoundException: liquibase.change.custom.RollbackRerunableCustomTaskChange
        at liquibase.change.custom.CustomChangeWrapper.load(CustomChangeWrapper.java:300)
        at liquibase.changelog.ChangeSet.toChange(ChangeSet.java:535)
        at liquibase.changelog.ChangeSet.handleChildNode(ChangeSet.java:460)
        at liquibase.changelog.ChangeSet.load(ChangeSet.java:384)
        at liquibase.changelog.DatabaseChangeLog.createChangeSet(DatabaseChangeLog.java:761)
        at liquibase.changelog.DatabaseChangeLog.handleChildNode(DatabaseChangeLog.java:395)
        at liquibase.changelog.DatabaseChangeLog.load(DatabaseChangeLog.java:364)
        at liquibase.parser.core.xml.AbstractChangeLogParser.parse(AbstractChangeLogParser.java:23)
        ... 47 more
Caused by: liquibase.exception.CustomChangeException: java.lang.ClassNotFoundException: liquibase.change.custom.RollbackRerunableCustomTaskChange
        at liquibase.change.custom.CustomChangeWrapper.setClass(CustomChangeWrapper.java:89)
        at liquibase.change.custom.CustomChangeWrapper.load(CustomChangeWrapper.java:298)
        ... 54 more
Caused by: java.lang.ClassNotFoundException: liquibase.change.custom.RollbackRerunableCustomTaskChange
        at java.base/java.net.URLClassLoader.findClass(URLClassLoader.java:471)
        at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:588)
        at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
        at java.base/java.lang.Class.forName0(Native Method)
        at java.base/java.lang.Class.forName(Class.java:398)
        at liquibase.change.custom.CustomChangeWrapper.setClass(CustomChangeWrapper.java:79)
        ... 55 more

I am not really familiar with Java, but I think everything is OK.

I am using 4.17.2 version over windows, but my plan is that it would run on a docker liquibase image. I need to know if this feature really works.

EDIT:
Also tryed this:

> jar tf .\RollbackRerunableCustomTaskChange.jar
META-INF/
META-INF/MANIFEST.MF
RollbackRerunableCustomTaskChange.class

Another Edit. After deleting CustomTaskRollback implementation:

> javap .\RollbackRerunableCustomTaskChange.class
Compiled from "RollbackRerunableCustomTaskChange.java"
public class liquibase.change.custom.RollbackRerunableCustomTaskChange implements liquibase.change.custom.CustomTaskChange {
  public liquibase.change.custom.RollbackRerunableCustomTaskChange();
  public java.lang.String getHelloTo();
  public void setHelloTo(java.lang.String);
  public void execute(liquibase.database.Database) throws liquibase.exception.CustomChangeException;
  public java.lang.String getConfirmationMessage();
  public void setUp() throws liquibase.exception.SetupException;
  public void setFileOpener(liquibase.resource.ResourceAccessor);
  public liquibase.exception.ValidationErrors validate(liquibase.database.Database);
}

Thanks in advance

I was able to find a post on StackOverflow from a while back with the same error. The solution there was to add an argument to specify a classpath,