При запуске из командной строки, если вы выбираете систему сборки Maven (то же самое работает для Gradle), вы позволяете плагинам делать всю работу за вас.
Когда вы запускаете из своей IDE основной класс,но не из встроенных окон Maven / Gradle, напротив, вы запускаете простые параметры командной строки java
.
И это приводит к двум разным вещам (но, конечно, с одинаковым конечным результатом), как вы уже выяснили через распечатку свойств.
Как уже указано в этом ответе для IntelliJ, но применимо к любой другой IDE или этой другой one для Eclipse существует два способа запуска проекта JavaFX 11, основанные на использовании или не использовании системы сборки Maven / Gradle.
проект JavaFX, без инструментов сборки
Чтобы запустить проект JavaFX из среды IDE, необходимо загрузить JavaFX SDK и добавить библиотекус различными javafx jar для вашей IDE, с путем, подобным /Users/<user>/Downloads/javafx-sdk-11/lib/
.
Теперь, чтобы запустить этот проект, даже если он не является модульным, вы должны добавить путь к этим модулям и включитьмодули, которые вы используете для параметров / аргументов виртуальной машины проекта.
Запускаете ли вы проект из IDE или из командной строки, вы будете запускать что-то вроде:
java --module-path /Users/<user>/Downloads/javafx-sdk-11/lib/ \
--add-modules=javafx.controls org.openjfx.hellofx.HelloFX
Обратите внимание, что даже если ваш проект не является модульным, вы все равно используетеМодули JavaFX, и поскольку вы не используете какой-либо инструмент для сборки, вам необходимо позаботиться о загрузке SDK.
Проект JavaFX, инструменты сборки
Если вы используете инструменты сборки Maven или Gradle, первое основное отличие заключается в том, что вам не нужно загружать JavaFX SDK.Вы включите в свой pom (или файл build.gradle), какие модули вам нужны, и Maven / Gradle сможет загрузить только эти модули (и зависимости) в ваш локальный репозиторий .m2 / .gradle.
КогдаВы запускаете свой основной класс из Maven exec:java
goal Вы используете плагин, и то же самое относится к задаче run
в Gradle.
На данный момент, выглядит как , когдавы запускаете:
mvn compile exec:java
или
gradle run
вы не добавляете вышеупомянутые аргументы VM, но факт в том, что Maven / Gradle позаботится об этом за вас.
Gradle
В случае Gradle это более очевидно, поскольку вы должны установить их в задаче run
:
run {
doFirst {
jvmArgs = [
'--module-path', classpath.asPath,
'--add-modules', 'javafx.controls'
]
}
}
Пока выSDK не нужен, classpath
содержит путь к вашему .m2 или .gradle репозиторию, куда были загружены артефакты javafx.
Maven
Для Maven, в то время как pom управляет зависимостями различных модулей javafx и устанавливает классификатор для загрузки специфичных для платформы модулей (см., Например, /Users/<User>/.m2/repository/org/openjfx/javafx-controls/11/javafx.controls-11.pom
), плагину удается настроить путь к классам и создать необходимые параметры для запуска проекта.
Короче говоря, новый класс, который не расширяется Application
, используется для вызова класса вашего приложения: HelloFX.main(args)
.
EDIT
См. Этот ответ для более подробного объяснения того, почему не удается запустить приложение JavaFX без пути к модулю .Но вкратце:
Эта ошибка происходит от sun.launcher.LauncherHelper в модуле java.base.Причина этого заключается в том, что главное приложение расширяет приложение и имеет основной метод.Если это так, LauncherHelper проверит наличие модуля javafx.graphics в качестве именованного модуля.Если этот модуль отсутствует, запуск прерывается.
Более подробное объяснение того, как работает плагин maven без установки module-path :
Если вы добавите уровень отладки (по умолчанию это информация) при выполнении целей Maven, вы получите более подробную информацию о том, что происходит за кулисами.
Запуск mvn compile exec:java
показывает:
...
[DEBUG] (f) mainClass = org.openjfx.hellofx.HelloFX
...
[DEBUG] Invoking : org.openjfx.hellofx.HelloFX.main()
...
И если вы проверите исходный код exec-maven-plugin
, вы можете найти в ExecJavaMojo::execute
, как метод main
класса Application вызывается из потока.
Thisэто именно то, что позволяет запускать класс Application из внешнего класса, который не расширяет класс Application, чтобы пропустить проверки.
Заключение
Выбор за вами - сборкаинструменты или нет, хотя в настоящее время их использование является предпочтительным вариантом, конечно.В любом случае, конечный результат будет одинаковым.
Но важно понять, в чем различия этих подходов и как ваша IDE справляется с ними.