java - 将 IntelliJ 中的 JavaFX 11 实现从“使用 IDE 中的 jvm 选项构建和运行”更改为“创建运行时映像”
问题描述
编辑#3(解决方案)
我没有使用任何建议的答案解决了这个问题。最后,我有一些文件夹和文件可以压缩和发送,不需要安装 java 并且可以通过双击 .bat 文件来运行。以下程序对我有用:
从头开始创建一个新的 gradle 项目
将所有模块/代码添加到 src/main/java 文件夹中
创建一个调用主方法的 AppLauncher.java
将所有 fxml/css 从其中一个 java 文件夹内移动到资源文件夹
确保您对 fxml-/css-files 的调用没有被错误地重构并使用以下代码:
//Main start method
Parent root = FXMLLoader.load(new File("fxml/main.fxml").toURI().toURL());
//Other FXML loading operations
FXMLLoader loader = null;
try { loader = new FXMLLoader(new File("fxml/GRAPHISO_proof.fxml").toURI().toURL()); }
...
对于样式表:
scene.getStylesheets().add("file:///" + new File("css/text-field-red-border.css").getAbsolutePath().replace('\\', '/'));
module-info.java
使用以下结构在 src/main/java 文件夹中创建:
module XYZ {
requires javafx.controls;
requires javafx.graphics;
requires java.desktop;
requires javafx.fxml;
requires javafx.base;
opens main.controller to javafx.fxml;
//Open ALL controller-modules (all of my modules have a controller-submodule, e.g. main/controller, dlog/controller, graphiso/controller, ...) to javafx.fxml
//...
exports main;
}
确保 gradle/wrapper/gradle-wrapper.properties 设置为不那么旧的 gradle (
distributionUrl=https\://services.gradle.org/distributions/gradle-6.3-bin.zip
)版本使用它作为你的 build.gradle:
buildscript {
repositories {
maven {
url "https://plugins.gradle.org/m2/"
}
}
dependencies {
classpath 'org.openjfx:javafx-plugin:0.0.8'
classpath 'com.github.jengelman.gradle.plugins:shadow:5.2.0'
}
}
plugins {
id 'java'
id 'org.beryx.jlink' version '2.19.0'
}
apply plugin: 'org.openjfx.javafxplugin'
apply plugin: 'com.github.johnrengelman.shadow'
group 'org.example.abc'
version '1.0'
sourceCompatibility = 1.14
repositories {
mavenCentral()
}
dependencies {
testCompile group: 'junit', name: 'junit', version: '4.12'
}
javafx {
sdk = 'C:\\Program Files\\Java\\javafx-sdk-14.0.1'
modules = [ 'javafx.controls', 'javafx.fxml', 'javafx.base' ]
}
jlink {
mainClassName = 'main.AppLauncher'
launcher {
name = 'Whatever you want as name'
}
}
tasks.jlink.doLast {
copy {
from('src/main/resources')
into("$buildDir/image/bin")
}
copy {
from 'C:\\Program Files\\Java\\javafx-sdk-14.0.1\\bin\\glass.dll',
'C:\\Program Files\\Java\\javafx-sdk-14.0.1\\bin\\javafx_font.dll',
'C:\\Program Files\\Java\\javafx-sdk-14.0.1\\bin\\prism_d3d.dll',
'C:\\Program Files\\Java\\javafx-sdk-14.0.1\\bin\\prism_sw.dll'
into("$buildDir/image/bin")
}
}
请注意我是如何在 tasks.jlink.doLast 中包含一些 dll 文件的。没有它们,程序会不断崩溃并引用 QuantumRenderer。
- 安装 openjdk-14.0.1 二进制文件并相应地设置您的 %JAVA_HOME%,同时安装 openjfx-14.0.1(程序需要一些如上所述的 DLL)
原始问题
我正在尝试通过仅使用 IntelliJ 中的“运行配置”功能从我在 JavaFX 11 中实现的项目创建运行时映像。在我看来,这里的一个大问题是我对 maven/gradle 的了解几乎不存在,而这些构建工具对于这一步至关重要。
在里面C:\Program Files\Java
我已经安装了:
javafx-sdk-11.0.2
和jdk-13.0.2
我将 IntellJ 的“运行配置”中的 VM 选项配置为--module-path "C:\Program Files\Java\javafx-sdk-11.0.2\lib" --add-modules javafx.controls,javafx.fxml
并将主类设置为“main.Main”。
我的项目结构如下所示:项目文件夹结构
突出显示的 Main.java 是一个常用的 Main 文件(扩展 Application,在 main 内部调用launch (args))。它可以加载位于其他包中的其他窗口。它不是一个启动器文件,它不扩展应用程序并调用实际的主文件(正如一些 gradle-building 解决方案所建议的那样)。
最初,我试图获得一个 .jar 文件,它可以在 Windows 和 Linux 上运行而无需任何其他参数。经过一番阅读,我认为这不是一个干净的解决方案,并且许多消息来源指出,在现代解决方案中,.jar 文件将被放在一起并附带一个包含所有必要参数的 .bat/.sh 文件。
我的问题是:如何最好地进行以及需要哪些配置/附加文件才能将这个“click-to-run-inside-IDE”项目转换为可以通过电子邮件或类似方式共享的“独立应用程序” ?
我试图通过 IntelliJ 创建一个新的 gradle 项目(遵循https://openjfx.io/openjfx-docs)并将源文件复制粘贴到 src/main/java 中。然后我尝试了提供的 build.gradle-file 并且 - 之后没有工作 - 进行了各种博客/论坛/等建议的一些更改。他们都不允许我通过 IntelliJ 或命令行运行项目。
这些方法中的大多数让我构建项目,但是当尝试使用“gradlew run”或调用“java -jar file.jar”运行时,由于类异常或说我仍然缺少 javafx 模块,我收到错误消息。我还尝试了一种将我当前的项目转换为 gradle-project 的方法,但这甚至不允许我在之后构建项目。
编辑 #1 (JPackageScriptFX)
我查看了 JPackageScriptFX 链接。现在我得到了一个mvn clean install
可以在我的机器上运行的安装程序(使用 ),但是在运行生成的可执行文件时,我收到一条错误消息,上面写着“无法启动 JVM”。
到目前为止我所做的是:
安装 jdk-14.0.1 并设置 JAVA_HOME,安装 wix311
创建了一个名为“bachelor_maven”的新 IntelliJ maven 项目
删除了初始 src 文件夹
在生成的 src/main/java 文件夹中添加了新模块“ZKP_Inspector”和我的旧模块
添加和编辑 src/main/logo/windows/duke.ico、两个 pom.xml 文件和来自JPackageScriptFX的 build_app.bat
实现了调用 Main.java 的 AppLauncher.java
我的配置文件:
新项目结构:Imgur
pom.xml(项目级别,baker_maven):Pastebin
pom.xml(模块级别,ZKP_Inspector):Pastebin
build_app.bat:Pastebin
编辑#2
我尝试--runtime-image target/java-runtime ^
从 build_app.bat 文件中的 jpackage 参数中删除,以便让 jpackage 决定要包含的内容。这增加了安装程序的文件大小(如预期的那样),但在尝试执行生成的程序时会导致相同的错误。
我还下载了 JMOD 文件,并在 build_app.bat 中的 jlink 任务中使用了它们,如此处所示。
所以我换成--add-modules %detected_modules%,%manual_modules% ^
了
--module-path "C:\Program Files\Java\javafx-jmods-11.0.2" --add-modules %detected_modules%,%manual_modules%,javafx.controls,javafx.fxml
这产生了另一个运行良好的安装程序,并且其生成的程序引发了相同的错误。
解决方案
好吧,我将尝试展示如何仅使用jlink来实现这一点。假设我们在目录“C:\Users\Alexiy\IdeaProjects\AnotherBuildTool\rundir”中有一个示例项目。它的结构是:
/rundir
--classes [compilation output]
--source [source code]
--images [runtime image output]
我有一个类'source\io\github\alexiyorlov\calculator\Program.java':
package io.github.alexiyorlov.calculator;
import javafx.application.Application;
import javafx.stage.Stage;
import java.nio.file.Path;
public class Program extends Application {
@Override
public void start(Stage primaryStage) throws Exception {
System.out.println("I'm a simple application");
primaryStage.show();
}
}
还有一个合适的'source\module-info.java':
module io.github.alexiyorlov{
requires javafx.controls;
requires javafx.graphics;
exports io.github.alexiyorlov.calculator;
}
如果我想以此制作运行时映像,jlink命令的语法将如下所示:
jlink --launcher [启动脚本的名称]=[对主类的引用] --module-path '[项目依赖jar的分隔列表+编译输出目录]' --add-modules [我的模块引用] -- compress=2 --output [生成的运行时映像的目录]
因此,对于我的示例项目,它解析为以下命令:
jlink
--launcher launch=io.github.alexiyorlov/io.github.alexiyorlov.calculator.Program
--module-path 'C:\Users\Alexiy\.m2\repository\org\openjfx\javafx-controls\11.0.2\javafx-controls-11.0.2-win.jar;C:\Users\Alexiy\.m2\repository\org\junit\jupiter\junit-jupiter-engine\5.7.0-M1\junit-jupiter-engine-5.7.0-M1.jar;C:\Users\Alexiy\.m2\repository\org\openjfx\javafx-base\11.0.2\javafx-base-11.0.2.jar;C:\Users\Alexiy\.m2\repository\org\openjfx\javafx-base\11.0.2\javafx-base-11.0.2-win.jar;C:\Users\Alexiy\.m2\repository\org\openjfx\javafx-graphics\11.0.2\javafx-graphics-11.0.2.jar;C:\Users\Alexiy\.m2\repository\dev\buildtool\json-tools\0.1.0\json-tools-0.1.0.jar;C:\Users\Alexiy\IdeaProjects\AnotherBuildTool\rundir\org\openjfx\javafx\11.0.2\javafx-11.0.2/.jar;C:\Users\Alexiy\.m2\repository\org\openjfx\javafx-controls\11.0.2\javafx-controls-11.0.2.jar;C:\Users\Alexiy\.m2\repository\org\openjfx\javafx-graphics\11.0.2\javafx-graphics-11.0.2-win.jar;C:\Users\Alexiy\IdeaProjects\AnotherBuildTool\rundir/classes'
--add-modules io.github.alexiyorlov
--compress=2
--output .\images\0.0.1
它将使用启动脚本“0.0.1\bin\launch”在目录“images\0.0.1”中创建一个图像。
请注意,我使用了一种自动方式来获取 --module-path 的正确参数;确保在其中包含类输出目录。
--add-modules 指定要包含的应用程序的哪些模块。
--output 指定一个目录来放置图像的所有文件。
--launcher 指定启动脚本的名称以及在“=”之后对主类的正确引用。
--compress=2 使其对图像应用 ZIP 压缩。
随时向我索取更多信息。
推荐阅读
- java - Java Apache POI - 是否可以获得比 getCellType 方法返回的更详细的单元格类型?
- laravel - Laravel查询嵌套多对多项目的多态关系
- ffmpeg - 使用 ffmpeg 时 Bash 权限被拒绝
- asp.net - 有没有办法告诉 CodeDomProvider Compiler 关于类中的共享函数?
- reactjs - TypeScript:“RefObject”类型上不存在“getContext”
' - javascript - NodeJS - 在 Windows 上解析另一个 JSON 中的 JSON 字符串时出现问题
- python - 守护程序目标函数在 Python 中不接受字符串参数
- json - 在 Spring 中使用占位符加载 Json
- typescript - vscode 中的 Aspnet 核心构建管道,尤其是 typescript - 2020 年
- c# - 按需从另一个类和方法中获取变量