我正在尝试让 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/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
),所以它可能会导致一些类加载问题,因为文件被加载两次?