Пакет #getImplementationVersion() возвращает null с собственным изображением (GraalVM/GluonFX)
У меня есть настольное приложение на основе JavaFX, для которого я создаю собственные образы с помощью GraalVM / GluonFX. Чтобы получить версию приложения во время выполнения, я ранее - когда был только толстый JAR приложения - использовал. Однако это возвращает
null
.
Я полагаю, это потому, что я неправильно установил записи манифеста? Моя конфигурация
gluonfx-maven-plugin
:
<plugin>
<groupId>com.gluonhq</groupId>
<artifactId>gluonfx-maven-plugin</artifactId>
<version>1.0.10</version>
<configuration>
<mainClass>${mainClass}</mainClass>
<nativeImageArgs>
<arg>--allow-incomplete-classpath</arg>
<arg>--initialize-at-build-time=org.pdfclown.Version</arg>
<arg>--no-fallback</arg>
</nativeImageArgs>
</configuration>
</plugin>
Есть ли способ настроить плагин так, чтобы
Package#getImplementationVersion()
возвращает версию приложения? Мне не удалось найти что-то в соответствующей документации . Кроме того, в 2020 году была решена с связаннаяэтим проблема в GraalVM.
1 ответ
Допустим, у вас есть проект Maven, и вы добавляете в свой основной класс приложения:
@Override
public void start(Stage primaryStage) throws Exception {
...
System.out.println("Main class version: " + getClass().getPackage().getImplementationVersion());
}
Если вы сделаете толстую банку с плагином тени и позаботитесь о добавлении необходимых записей манифеста, таких как (скажем,
1.0
), когда вы запускаете:
java --module-path=PATH_TO_FX --add-modules javafx.controls,javafx.fxml -jar my-fat-jar.jar
он должен печатать:
Main class version: 1.0
Однако если вы запустите
mvn javafx:run
он печатает:
Main class version: null
как вы сообщили.
Причина этого: в пути к классам нет манифеста, а классы (
target/classes
) не упакованы в банку.
Если ваш проект имеет стороннюю зависимость, которая включает манифест с
Implementation-Version
вход (скажем
2.0
), делает:
@Override
public void start(Stage primaryStage) throws Exception {
...
System.out.println("3rd party Main class version: " + com.my.third.party.MainClass.class.getPackage().getImplementationVersion());
}
заработает:
mvn javafx:run
[INFO] --- javafx-maven-plugin:0.0.8:run (default-cli) @ MyProject ---
3rd party Main class version: 2.0.
потому что банка является зависимостью упакованных классов с манифестом.
И делаем нативный образ
mvn gluonfx:build gluonfx:nativerun
также работает:
[INFO] --- gluonfx-maven-plugin:1.0.10:nativerun (default-cli) @ MyProject ---
[Mon Dec 20 21:29:16 CET 2021][INFO] ==================== RUN TASK ====================
[Mon Dec 20 21:29:16 CET 2021][INFO] [SUB] 2021-12-20 21:29:16.810 MyProject[23068:414510] Starting Gluon VM...
[Mon Dec 20 21:29:16 CET 2021][INFO] [SUB] Dec 20, 2021 9:29:16 PM com.sun.javafx.application.PlatformImpl startup
[Mon Dec 20 21:29:16 CET 2021][INFO] [SUB] WARNING: Unsupported JavaFX configuration: classes were loaded from 'unnamed module @21c815e4'
[Mon Dec 20 21:29:16 CET 2021][INFO] [SUB] 3rd party Main class version: 2.0
Итак, на данный момент я вижу три варианта:
- Переместите свой основной код в модуль, опубликуйте банку и добавьте ее в свой основной проект в качестве зависимости, это должно работать.
- Переместите пары "ключ-значение" манифеста в файл свойств и используйте подключаемый модуль ресурсов Maven. Это должно работать из коробки с плагином GluonFX (убедитесь, что вы добавили расширение свойств в список ресурсов). Это должно быть самым простым.
- Сообщите о проблеме на Substrate, чтобы запросить манифест. Пока что Substrate создает jar из классов проекта , так что теоретически у него тоже может быть манифест, и в него можно было бы занести какие-то ключи-значения, исходящие из конфигурации плагина. Добавить манифест легко, проблема заключается в добавлении изменений в конфигурацию для передачи ключей-значений.