В Java / JavaFX 11 теневая / жирная банка не будет работать.
Как вы можете прочитать здесь :
Эта ошибка происходит от sun.launcher.LauncherHelper
в модуле java.base.Причина этого заключается в том, что приложение Main расширяет Application
и имеет метод main.Если это так, LauncherHelper
проверит наличие модуля javafx.graphics как именованного модуля:
Optional<Module> om = ModuleLayer.boot().findModule(JAVAFX_GRAPHICS_MODULE_NAME);
Если этот модуль отсутствует, запускпрерваноСледовательно, в этом случае использование библиотек JavaFX в качестве jar-файлов на пути к классам недопустимо.
Более того, каждый jar-файл JavaFX 11 имеет файл module-info.class
на корневом уровне.
Когда вы объединяете все содержимое банок в одну толстую банку, что происходит с этими файлами с одинаковым именем и одинаковым расположением?Даже если толстый кувшин хранит их все, как он идентифицируется как один модуль?
Есть запрос на поддержку, но он еще не решен: http://openjdk.java.net/projects/jigsaw/spec/issues/#MultiModuleExecutableJARs
Предоставляет средство для создания исполняемого модульного «uber-JAR», который содержит более одного модуля, сохраняя идентификаторы и границы модулей, так что все приложение может быть доставлено как один артефакт.
Плагин тени все еще имеет смысл объединить все ваши другие зависимости в одну банку, но в конце концов вам придется запустить что-то вроде:
java --module-path <path-to>/javafx-sdk-11/lib \
--add modules=javafx.controls -jar my-project-ALL-1.0-SNAPSHOT.jar
Это означает, что послевсе, вам придется установить JavaFX SDK (для каждой платформы), чтобы запустить тот jar-файл, который использовал зависимости JavaFX от maven central.
В качестве альтернативы вы можете попробовать использовать jlink
для создания облегченной JRE,но ваше приложение должно быть модульным.
Также вы можете использовать Javapackager для генерации установщика для каждой платформы.См. http://openjdk.java.net/jeps/343, который создаст упаковщик для Java 12.
Наконец, есть экспериментальная версия Javapackager, которая работает с Java 11 / JavaFX 11: http://mail.openjdk.java.net/pipermail/openjfx-dev/2018-September/022500.html
EDIT
Поскольку средство запуска Java проверяет, расширяет ли основной класс javafx.application.Application
, и в этом случае требуется, чтобы среда выполнения JavaFX была доступна в виде модулей (а не в виде jars), возможноЧтобы обойти это, нужно добавить новый Main класс, который будет основным классом вашего проекта, и этот класс будет вызывать ваш класс JavaFX Application.
Еслиу вас есть пакет javafx11
с классом приложения:
public class HelloFX extends Application {
@Override
public void start(Stage stage) {
String javaVersion = System.getProperty("java.version");
String javafxVersion = System.getProperty("javafx.version");
Label l = new Label("Hello, JavaFX " + javafxVersion + ", running on Java " + javaVersion + ".");
Scene scene = new Scene(new StackPane(l), 400, 300);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Затем вам нужно добавить этот класс в этот пакет:
public class Main {
public static void main(String[] args) {
HelloFX.main(args);
}
}
И в вашем файле сборки:
mainClassName='javafx11.Main'
jar {
manifest {
attributes 'Main-Class': 'javafx11.Main'
}
from {
configurations.compile.collect { it.isDirectory() ? it : zipTree(it) }
}
}
Теперь вы можете запустить:
./gradlew run
или
./gradlew jar
java -jar build/libs/javafx11-1.0-SNAPSHOT.jar
Конечная цель заключается виметь модули JavaFX в качестве именованных модулей на пути к модулю, и это выглядит как быстрый / безобразный обходной путь для проверкиВаше приложение.Для распространения я бы все же предложил вышеупомянутые решения.