在 Liquibase 中运行 customChange 时出现 ClassNotFound 异常

问题描述 投票:0回答:1

我正在尝试让 Liquibase 使用 customChange 运行自定义脚本,这是我的设置:

变更日志.xml

<databaseChangeLog
    xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
    xmlns:pro="http://www.liquibase.org/xml/ns/pro"
    xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog
        http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-latest.xsd
        http://www.liquibase.org/xml/ns/dbchangelog-ext
        http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd
        http://www.liquibase.org/xml/ns/pro
        http://www.liquibase.org/xml/ns/pro/liquibase-pro-latest.xsd">

    <changeSet id="1" author="test">
        <customChange class="com.example.RunCustomCommand">
        </customChange>
    </changeSet>

</databaseChangeLog>

Dockerfile

FROM liquibase:latest

WORKDIR /node-app
USER root
COPY . .
RUN apt update -y
RUN apt install default-jdk -y
RUN javac -cp /liquibase/internal/lib/liquibase-core.jar RunCustomCommand.java
RUN jar cvf run-custom-command.jar RunCustomCommand.class
RUN cp /node-app/run-custom-command.jar /liquibase/lib/run-custom-command.jar

CMD [ "sh" ]

docker-compose.yml

version: "3.1"

services:
  db:
    container_name: db
    image: postgres:11-alpine
    ports:
      - "5432:5432"
    environment:
      POSTGRES_PASSWORD: postgres
      POSTGRES_DB: postgres
    networks:
      - test-liqui
  lobo-liquibase:
    container_name: test-liquibase
    depends_on:
      - db
    build:
      context: ./
      dockerfile: Dockerfile
    entrypoint: ["/bin/sh", "-c"]
    command:
      - |
        ls
        liquibase update --classpath=./run-custom-command.jar --changelog-file=changelog.xml --username=postgres --password=postgres --url=jdbc:postgresql://db:5432/postgres
    networks:
      - test-liqui
networks:
  test-liqui:

运行自定义命令.java

package com.example;

import liquibase.change.custom.*;
import liquibase.database.Database;
import liquibase.exception.CustomChangeException;
import liquibase.exception.SetupException;
import liquibase.exception.ValidationErrors;
import liquibase.resource.ResourceAccessor;

public class RunCustomCommand implements CustomTaskChange {

    private ResourceAccessor resourceAccessor;

    @Override
    public void execute(Database database) throws CustomChangeException {
        System.out.printf("Hello %s!", "World");
    }

    @Override
    public String getConfirmationMessage() {
        return "Custom task executed successfully.";
    }

    @Override
    public void setUp() throws SetupException {
        // Any setup logic here
    }

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

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

这样,我将 RunCustomCommand.java 编译为 run-custom-command.jar 并将其传递给 Liquibase 命令: --classpath=./run-custom-command.jar 但是,当我运行 docker compose up 时,我仍然得到

test-liquibase  | ERROR: Exception Primary Class:  ClassNotFoundException
test-liquibase  | ERROR: Exception Primary Reason:  com.example.RunCustomCommand
test-liquibase  | ERROR: Exception Primary Source:  PostgreSQL 11.22
test-liquibase  | 
test-liquibase  | Unexpected error running Liquibase: com.example.RunCustomCommand

我还尝试将 run-custom-command.jar 复制到 /liquibase/lib 但没有帮助。我对 Java 不熟悉,我将来想做的是从该类运行 Node.js 脚本。 知道我做错了什么吗?

liquibase classnotfoundexception
1个回答
0
投票

由于文件位于 /liquibase/lib 内,因此不需要 --classpath 参数。尝试删除它。

为什么?您正在复制 liquibase/lib 目录中的文件:

RUN cp /node-app/run-custom-command.jar /liquibase/lib/run-custom-command.jar

Liquibase 自动将此目录中的所有内容加载到类路径中,如果文件在那里,则无需使用类路径。之后,您使用

--classpath
再次指向它(我相信它应该是
--classpath=./lib/run-custom-command.jar
),所以它可能会导致一些类加载问题,因为文件被加载两次?

© www.soinside.com 2019 - 2024. All rights reserved.