flyway只有在用jlink组装应用程序后运行应用程序,才能在类路径中找到迁移

cl25kdpy  于 2021-06-30  发布在  Java
关注(0)|答案(1)|浏览(342)

我正在使用gradle的badass jlink插件,以便将java、javafx应用程序及其依赖项组装到一个工件(自定义运行时)中,这样我就只能共享 zip 文件。
我为我的问题创建了一个mwe,可以在这里找到:https://github.com/victoratpl/jlink_badass_flyway_classpath_problem
执行后 prepareModulesDir 此插件的任务,在 build/jlinkbase/jlinkjars 以下是 jar 学生: jar 具有模块化依赖关系(包含 module-info.class 从一开始; javafx-base-12.0.1-linux.jar , derby-10.15.1.3.jar 等等),
一网打尽 jar 包含所有非模块化依赖项文件的依赖项(作者没有通过添加 module-info.java 文件; jlink_badass_flyway_classpath_problem.merged.module-0.1.0-alpha.jar ), jar 是“包罗万象”的代理 jar 文件(通过使用 require transitive 中的子句 module-info.java ; flyway-core-6.1.4.jar ), jar 应用程序主模块的类和资源( jlink_badass_flyway_classpath_problem-0.1.0-alpha.jar ).
更多关于如何 badass-jlink-plugin 您可以在以下文档中找到作品:https://badass-jlink-plugin.beryx.org/releases/latest/#_how_it_works
应用程序的主模块包含资源( .sql 中的文件 src/main/resources/db/migration )和班级( .java 中的文件 src/main/java/db/migration )它们是flyway库的迁移。
如果我使用 jlink 任务( ./jlink.sh 脚本)并使用系统安装的java运行应用程序( run_system_java.sh ,执行 /usr/lib/jvm/java-11-oracle/bin/java --module-path /usr/lib/jvm/java-11-oracle/jmods/:./build/jlinkbase/jlinkjars --module jlink_badass_flyway_classpath_problem/app.Main )然后flyway正常工作(查找并应用两个迁移)。
如果我使用自定义创建的运行时运行应用程序( ./run_assembled_java.sh ,执行 ./build/image/bin/java -m jlink_badass_flyway_classpath_problem/app.Main )我收到以下警告:

Jan 24, 2020 8:22:38 PM org.flywaydb.core.internal.scanner.classpath.ClassPathScanner findResourceNames
WARNING: Unable to resolve location classpath:db/migration

所以在执行 jlinkbadass-jlink-plugin 有些东西坏了,因为 db/migration 创建后找不到 modules 自定义运行时的文件。
这是由执行的命令 jlink 任务:

/usr/lib/jvm/java-11-oracle/bin/jlink -v --compress 2 --no-header-files --no-man-pages --module-path /usr/lib/jvm/java-11-oracle/jmods/:/home/piotr/IdeaProjects/jlink_badass_flyway_classpath_problem/build/jlinkbase/jlinkjars --add-modules jlink_badass_flyway_classpath_problem --output /home/piotr/IdeaProjects/jlink_badass_flyway_classpath_problem/build/image

我还附上 gradle jlink 以及 jimage list build/image/lib/modules : https://gist.github.com/victoratpl/69e50e1738429548d1e6d8070e37b062
我认为它这样做的主要原因是 ClassPathScanner.java 当使用不同的java(安装了系统并由jlink创建了自定义运行时)运行时,flyway的行为不同。
在第一个场景中,它会找到一个url: jar:file:///home/piotr/IdeaProjects/jlink_badass_flyway_classpath_problem/build/jlinkbase/jlinkjars/jlink_badass_flyway_classpath_problem-0.1.0-alpha.jar!/db/migration/ ,在第二个-它没有( classLoader.getResources("db/migration").nextElement() 投掷 java.util.NoSuchElementException ; 但是 classLoader.getResources("db/migration/V1__Initial_version.sql").nextElement() 工作)。
我提供了第二个场景的屏幕截图(使用自定义java运行时):


我相信在使用classloader时会遇到一些问题 modules 从java自定义运行时。为什么使用时不能查找目录 jrt 基于URL?
如果有人能指引我,我会很感激的。

2ul0zpep

2ul0zpep1#

不知道为什么它在这两个场景中的行为不同,但是如果您将它们放在类路径上,flyway的classpathscanner会找到这些资源。为此,可以复制映像的子目录中的资源,并将该子目录添加到类路径:

tasks.jlink {
    doLast {
        copy {
            from 'src/main/resources'
            into "$imageDir/bin/data"
        }
    }
}

jlink {
    ...
    launcher {
        ...
        jvmArgs = ['-cp', '$DIR/data/']
    }
}

我向您的mwe提交了上述更改作为请求:https://github.com/victoratpl/jlink_badass_flyway_classpath_problem/pull/1

相关问题