当您从Gradle项目运行可执行文件时,是否捆绑在JavaFX中? [英] Bundle in JavaFX when you run the executable from a Gradle project?

查看:121
本文介绍了当您从Gradle项目运行可执行文件时,是否捆绑在JavaFX中?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在过去的几天里,我一直在努力尝试着通往圣杯:Gradle + Java 11 + JavaFX +用Groovy而不是Java编写我的所有应用程序和测试代码.

Over the past few days I've been tearing what's left of my hair out trying to get to the Holy Grail: Gradle + Java 11 + JavaFX + writing all my app and testing code in Groovy, not Java.

几个问题之一是Groovy 2(甚至是Groovy 3)还不能应付Java 9+模块,这是聪明的解决方案.

One of several problems is that Groovy 2 (even Groovy 3) can't yet cope with Java 9+ modules, which rules one clever solution out.

但是我设法将Gradle项目整合在一起,该项目实际上不仅成功完成了所有事情,包括运行"任务(来自应用程序"插件),还使用TestFX运行了测试!实际上,这确实是使用Java 11,Groovy 2.5.9,JavaFX 13等.

But I have managed to get a Gradle project together which not only does virtually everything successfully, including the "run" task (from the "application" plugin), and runs tests using TestFX! This is indeed using Java 11, Groovy 2.5.9, JavaFX 13, etc.

它甚至会执行任务"installdist"(包含在build.gradle中).这样会产生一个带有"lib"目录的可执行文件,其中包含您需要独立运行的所有jar的目录(如任务"assembly",仅未压缩).

It will even execute the task "installdist" (when included in build.gradle). That produces an executable with a "lib" directory full of all the jars you need to run independently (like task "assemble", only not compressed).

问题是,当我执行该可执行文件时,我现在得到的是经典的错误:缺少JavaFX运行时组件,并且是运行此应用程序所必需的".仍然对此感到困惑,因为目录[project dir]/build/install/GradleExp/lib确实包含不少于7个JavaFX .jar.

The trouble is, when I execute that executable I get the by now classic "Error: JavaFX runtime components are missing, and are required to run this application". Still confused why that happens, as the directory [project dir]/build/install/GradleExp/lib does indeed contain no fewer than 7 JavaFX .jars.

我想我已经尽力尝试按常规方式配置Gradle了:考虑到我正在将Groovy用于应用程序和测试代码,我认为无法配置Gradle项目来获取"installdist"以进行生产准备运行的启用JavaFX的可执行文件.但是...生成此文件之后, 可以做些什么吗,就像我可以运行的某个命令那样,将JavaFX文件引入并链接到其中?即使这涉及到不完美地链接到某些JavaFX jar文件或位置?

I think I've exhausted what I can do trying to configure Gradle conventionally: given that I'm using Groovy for app and testing code I don't think it's possible to configure the Gradle project to get "installdist" to produce a ready-to-run JavaFX-enabled executable. But... is there something I can do after having produced this, like some command I could run that would somehow bring in the JavaFX files and link them in? Even if this involves linking inelegantly to some JavaFX jar file(s) or locations?

或者也许我可以使用由.../build/scripts下的"build"任务生成的可执行sh脚本文件?定义CLASSPATH时,将在开头插入上述7个JavaFX .jar文件:

Or maybe I could use the executable sh script file generated by the "build" task under .../build/scripts ? This ropes in the above-mentioned 7 JavaFX .jar files at the start when defining the 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:...

...当我尝试运行该脚本时,我得到:

... when I try to run that script I get:

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

编辑
这是一件有趣的事情:实际上,该脚本文件中的APP_HOME原来是[项目目录]/build.但是在该目录下没有目录"lib".有一个目录"libs",其中仅包含一个文件:GradleExp-1.0.jar,27 kB,不是凭空想象的胖" jar.

edit
Here's a funny thing: in fact APP_HOME in that script file turns out to be [project directory]/build. But under that there is no directory "lib". There is a directory "libs" which contains precisely one file: GradleExp-1.0.jar, 27 kB, not a "fat" jar by any stretch of the imagination.

我刚刚从"installdist"任务复制了"lib"目录到/build,并运行了该脚本文件:再次,尽管所有这些JavaFX jar现在都可用,但我还是再次得到了"".错误:JavaFX运行时组件丢失,并且是运行此应用程序所必需的".嗯...我有很多东西要学.

I just copied the "lib" directory from the "installdist" task up to /build, and ran that script file: again, despite having all those JavaFX jars now available, I again get "Error: JavaFX runtime components are missing, and are required to run this application". Hmmm... I have much to learn.

推荐答案

Slaw和cfrick在他们的评论中提出了我的问题的答案.我认为这可能对某些人有用.

Slaw and cfrick came up with the answer to my question in their comments. I thought this might come in useful for some.

如果要在类路径上使用JavaFX模块,则创建一个单独的主类,该主类不扩展Application并从main方法调用Application.launch(YourApp.class, args).

If you want the JavaFX modules on the class-path then create a separate main class which does not extend Application and invoke Application.launch(YourApp.class, args) from the main method.

cfrick的示例示例工作Gradle项目位于此处.我添加了以下行:

cfrick's example stripped-down working Gradle project is here. I added the following line:

installDist{}

...这将提供一个新任务:./gradlew installdist然后将在build/install/下生成一个可执行文件.

... this makes a new task available: ./gradlew installdist will then produce an executable under build/install/.

万一cfrick的github页面消失了,build.gradle就是这样:

In case cfrick's github page goes away, build.gradle is like this:

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就像这样:

and src/main/groovy/ofx/App.groovy is like this:

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()
    }

}

这篇关于当您从Gradle项目运行可执行文件时,是否捆绑在JavaFX中?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆