Основываясь на опубликованном проекте MVCE , вот несколько изменений, которые необходимы для работы проекта:
build.gradle
Исходя из этого:
plugins {
id 'application'
id 'org.openjfx.javafxplugin' version '0.0.8'
id 'org.beryx.jlink' version '2.12.0'
}
group 'me.project.desktop'
version '1.0-SNAPSHOT'
sourceCompatibility = 1.8
repositories {
mavenCentral()
}
dependencies {
compile group: 'uk.co.caprica', name: 'vlcj', version: '4.2.0'
compile group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.0.1'
compile group: 'com.google.http-client', name: 'google-http-client', version: '1.23.0'
compile group: 'com.jfoenix', name: 'jfoenix', version: '8.0.9'
compile group: 'org.slf4j', name: 'slf4j-simple', version: '1.7.28'
}
javafx {
version = "13"
modules = [ 'javafx.controls', 'javafx.fxml', 'javafx.base', 'javafx.graphics', 'javafx.media' ]
}
mainClassName = "me.project.mosaic.Main"
jlink {
options = ['--strip-debug', '--compress', '2', '--no-header-files', '--no-man-pages']
launcher {
name = 'mosaico-desktop'
}
}
Необходимые изменения:
JFoenix установлен на 8.0.9, что предназначено для Java 1.8. Если вы работаете с Java 11+, вы получите исключение:
Caused by: java.lang.ClassNotFoundException: com.sun.javafx.css.converters.PaintConverter
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:583)
Начиная с JDK 9, CSS-конвертеры являются публичным API, поэтому вам нужен JFoenix для 9, например 9.0.9.
Для справки см. post .
- Используйте JDK 11, а не 12 или 13
Элемент управления JFXTextField JFoenix имеет постоянную проблему с использованием отражения для доступа к частному API.
java.lang.IllegalAccessException: class com.jfoenix.skins.JFXTextFieldSkin cannot access a member of class javafx.scene.control.skin.TextFieldSkin (in module javafx.controls) with modifiers "private"
at java.base/jdk.internal.reflect.Reflection.newIllegalAccessException(Reflection.java:376)
...
java.lang.IllegalAccessException: class com.jfoenix.skins.JFXTextFieldSkin cannot access a member of class javafx.scene.control.skin.TextFieldSkin (in module javafx.controls) with modifiers "private"
at java.base/jdk.internal.reflect.Reflection.newIllegalAccessException(Reflection.java:376)
at java.base/java.lang.reflect.AccessibleObject.checkAccess(AccessibleObject.java:639)
...
и это вызывает исключение нулевого указателя:
Caused by: java.lang.NullPointerException
at com.jfoenix.skins.JFXTextFieldSkin.updateTextPos(JFXTextFieldSkin.java:109)
При работе с Java 11 все работает нормально.
Для справки, смотрите эту запись .
JFoenix использует частный API, поэтому он требует кучу экспортов, чтонеобходимо добавить к аргументам виртуальной машины, например:
run {
jvmArgs = [
"--add-exports=javafx.controls/com.sun.javafx.scene.control.behavior=ALL-UNNAMED",
"--add-exports=javafx.controls/com.sun.javafx.scene.control=ALL-UNNAMED",
"--add-exports=javafx.base/com.sun.javafx.binding=ALL-UNNAMED",
"--add-exports=javafx.graphics/com.sun.javafx.stage=ALL-UNNAMED",
"--add-exports=javafx.controls/com.sun.javafx.scene.control.behavior=ALL-UNNAMED"
]
}
Для справки см. this .
Это будет результирующий файл build.gradle
:
plugins {
id 'application'
id 'org.openjfx.javafxplugin' version '0.0.8'
id 'org.beryx.jlink' version '2.12.0'
}
group 'me.project.desktop'
version '1.0-SNAPSHOT'
sourceCompatibility = 11
repositories {
mavenCentral()
}
dependencies {
compile group: 'uk.co.caprica', name: 'vlcj', version: '4.2.0'
compile group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.0.1'
compile group: 'com.google.http-client', name: 'google-http-client', version: '1.23.0'
compile group: 'com.jfoenix', name: 'jfoenix', version: '9.0.9'
compile group: 'org.slf4j', name: 'slf4j-simple', version: '1.7.28'
}
javafx {
version = "13"
modules = [ 'javafx.controls', 'javafx.fxml', 'javafx.base', 'javafx.graphics', 'javafx.media' ]
}
run {
jvmArgs = ["--add-exports=javafx.controls/com.sun.javafx.scene.control.behavior=ALL-UNNAMED",
"--add-exports=javafx.controls/com.sun.javafx.scene.control=ALL-UNNAMED",
"--add-exports=javafx.base/com.sun.javafx.binding=ALL-UNNAMED",
"--add-exports=javafx.graphics/com.sun.javafx.stage=ALL-UNNAMED",
"--add-exports=javafx.controls/com.sun.javafx.scene.control.behavior=ALL-UNNAMED"
]
}
mainClassName = "me.project.mosaic.Main"
jlink {
options = ['--strip-debug', '--compress', '2', '--no-header-files', '--no-man-pages']
launcher {
name = 'mosaico-desktop'
}
}
Выполнение (с JDK 11):
./gradlew clean run
будет работать.
Модульный проект
Для запускаjlink
, нужно создать модульДескриптор r, например:
module mosaic.viewer {
requires javafx.controls;
requires javafx.fxml;
requires com.jfoenix;
requires vlcj;
requires jackson.annotations;
requires jackson.databind;
requires jackson.core;
requires google.http.client;
requires org.slf4j;
requires jsr305;
opens me.project.mosaic.login to javafx.fxml;
exports me.project.mosaic;
}
Поскольку FXML использует отражение, вы должны открыть для модуля javafx.fxml
пакет (ы) с помощьюконтроллер (ы). В этом случае: opens me.project.mosaic.login to javafx.fxml;
.
Поскольку теперь у вас есть именованный модуль, --add-exports
теперь имеет значение com.jfoenix
вместо ALL-UNNAMED
.
Выполнение (с JDK 11):
./gradlew clean jlink
создаст пользовательское изображение, и вы сможете запустить сгенерированное изображение из сценария запуска:
build/image/bin/mosaic-desktop
IDE
Если вы запускаете проект из IDE (IntelliJ), а не из терминала, убедитесь, что вы используете окно Gradle для IntelliJ, которое покажет вампроект и доступные задачи.
Важно установить в структуре проекта -> Проект SDK проекта и уровень языка на 11.
Также в окне Gradle есть кнопка настроек, нажмите на нееи убедитесь, что JVM Gradle также установлен в JDK 11.
Вы можете запустить из этого окна:
Наконец, вы также можете создавать конфигурации Run, но неНа Gradle, с вышеуказанными задачами.