Я использую Gradle's badass-jlink-plugin для сборки java, моего приложения JavaFX и его зависимостей в один артефакт - пользовательскую среду выполнения - так что я могу поделиться только zip
файлом.
Я создал MWE для своей проблемы, которая доступна здесь: https://github.com/VictorAtPL/jlink_badass_flyway_classpath_problem
После выполнения prepareModulesDir
задачи этого плагина, в build/jlinkbase/jlinkjars
есть следующие jar
s:
jar
s с зависимостями, которые были модульными (содержит module-info.class
с начала; javafx-base-12.0.1-linux.jar
, derby-10.15.1.3.jar
, et c. ), - зависимость для всех
jar
, которая содержит все файлы зависимостей, которые не были модульными (авторы не сделали их модульными, добавив, среди прочего, module-info.java
file; 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
Таким образом, во время выполнения jlink
с помощью badass-jlink-plugin
что-то прерывается, потому что db/migration
невозможно найти после создания файла modules
для пользовательской среды выполнения.
Это команда, выполняемая jlink
task:
/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
из Flyway действует по-разному при работе с h разные javas (устанавливаемые системой и настраиваемые среды выполнения, созданные jlink).
В первом сценарии он находит 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()
throws java.util.NoSuchElementException
; но classLoader.getResources("db/migration/V1__Initial_version.sql").nextElement()
работает).
Я предоставляю скриншоты для второго сценария (с пользовательским java временем выполнения):
![getResources on directory](https://i.stack.imgur.com/8aYuV.png)
Я полагаю, что есть некоторая проблема с classLoader при работе с modules
из java пользовательской среды выполнения. Почему я не могу искать каталоги при использовании jrt
основанных URL-адресов?
Я был бы признателен, если бы кто-нибудь помог мне.