Пакет в JavaFX, когда вы запускаете исполняемый файл из проекта Gradle? - PullRequest
0 голосов
/ 08 марта 2020

За последние несколько дней я рвал то, что осталось от моих волос, пытаясь добраться до Святого Грааля: Gradle + Java 11 + JavaFX +, пишущий все мое приложение и тестирующий код в Groovy, а не Java.

Одна из нескольких проблем заключается в том, что Groovy 2 (даже Groovy 3) еще не может справиться с Java 9+ модулями, что определяет одно умное решение out.

Но мне удалось собрать проект Gradle, который не только делает практически все успешно, включая задачу «Выполнить» (из плагина «application»), но и запускает тесты с использованием TestFX! Это действительно использует Java 11, Groovy 2.5.9, JavaFX 13 и т. Д. c.

. Он даже выполнит задачу "installdist" (если она включена в build.gradle). В результате получается исполняемый файл с каталогом "lib", полным всех jar-файлов, необходимых для независимой работы (например, задача "сборка", только не сжатая).

Проблема в том, что при выполнении этого исполняемого файла я получаю к настоящему моменту classi c "Ошибка: отсутствуют компоненты времени выполнения JavaFX, и они необходимы для запуска этого приложения" . Все еще не понимают, почему это происходит, поскольку каталог [project dir] / build / install / GradleExp / lib действительно содержит не менее 7 файлов JavaFX .jars.

Я думаю, что исчерпал все, что могу сделать, пытаясь Конфигурируем Gradle условно: учитывая, что я использую Groovy для приложения и тестирования кода, я не думаю, что можно настроить проект Gradle так, чтобы он вызывал "installdist" для создания готового к запуску исполняемого файла с поддержкой JavaFX. Но ... есть ли что-то, что я могу сделать после того, как произвёл это, как какая-то команда, которую я мог выполнить, которая каким-то образом привела бы файлы JavaFX и связала бы их? Даже если это связано с ненадлежащим связыванием с каким-либо jar-файлом (файлами) JavaFX или местоположениями?

Или, возможно, я мог бы использовать исполняемый файл сценария sh, созданный задачей "build" в ... / build / scripts ? Это ввязывается в вышеупомянутые 7 файлов JavaFX .jar в начале при определении CLASSPATH:

...
CLASSPATH=$APP_HOME/lib/GradleExp-1.0.jar:
$APP_HOME/lib/commons-math3-3.6.1.jar:
$APP_HOME/lib/guava-27.0.1-jre.jar:
$APP_HOME/lib/javafx-fxml-13-linux.jar:
$APP_HOME/lib/javafx-controls-13-linux.jar:
$APP_HOME/lib/javafx-controls-13.jar:
$APP_HOME/lib/javafx-graphics-13-linux.jar:
$APP_HOME/lib/javafx-graphics-13.jar:
$APP_HOME/lib/javafx-base-13-linux.jar:
$APP_HOME/lib/javafx-base-13.jar:...

... когда я пытаюсь запустить этот скрипт, я получаю:

mike@M17A /.../GradleExp/build/scripts $  ./GradleExp
Error: Could not find or load main class SceneSwitcher
Caused by: java.lang.ClassNotFoundException: SceneSwitcher

edit
Вот забавная вещь: на самом деле APP_HOME в этом файле сценария оказывается [каталог проекта] / build. Но под этим нет каталога "lib". Существует каталог "libs", который содержит ровно один файл: GradleExp-1.0.jar, 27 КБ, а не "толстый" фляга на любом воображении.

Я только что скопировал каталог "lib" из задача "installdist" до / build и запускала этот файл скрипта: опять же, несмотря на то, что теперь доступны все эти jar-файлы JavaFX, я снова получаю "Ошибка: отсутствуют компоненты времени выполнения JavaFX, и они необходимы для запуска этого приложения" . Хммм ... мне нужно многому научиться.

1 Ответ

1 голос
/ 13 марта 2020

Slaw и cfrick придумали ответ на мой вопрос в своих комментариях. Я подумал, что это может пригодиться для некоторых.

Если вы хотите, чтобы модули JavaFX были указаны на пути к классам, создайте отдельный основной класс, который не расширяет Application, и вызовите Application.launch(YourApp.class, args) из main method.

Пример урезанного рабочего проекта cfrick Gradle: здесь . Я добавил следующую строку:

installDist{}

... это делает новую задачу доступной: ./gradlew installdist создаст исполняемый файл в build / install /.

В случае, если cfrick github page Уходит, build.gradle выглядит следующим образом:

plugins {
    id 'groovy'
    id 'application'
    id 'org.openjfx.javafxplugin' version '0.0.8'
}

repositories {
    jcenter()
}

javafx {
    version = "11.0.2"
    modules = [ 'javafx.controls' ]
}

dependencies {
    implementation 'org.codehaus.groovy:groovy:3.+'
}

application {
    mainClassName = 'ofx.App'
}

installDist{} // my addition

и src / main / groovy / ofx / App. groovy выглядит так:

package ofx

import javafx.application.Application
import javafx.scene.Scene
import javafx.scene.control.Label
import javafx.scene.layout.StackPane
import javafx.stage.Stage

class App {
    static void main(String[] args) {
        Application.launch(HelloFx, args)
    }
}

class HelloFx extends Application {

    @Override
    void start(Stage stage) {
        def javaVersion = System.getProperty("java.version")
        def javafxVersion = System.getProperty("javafx.version")
        Label l = new Label("Hello, JavaFX $javafxVersion, running on Java $javaVersion.")
        Scene scene = new Scene(new StackPane(l), 640, 480)
        stage.setScene(scene)
        stage.show()
    }

}
...