【问题标题】:I have no clue what I'm doing trying to export JavaFx as a Jar/Exe我不知道我在做什么尝试将 JavaFx 导出为 Jar/Exe
【发布时间】:2021-08-30 10:29:16
【问题描述】:

我正在尽最大努力导出我的 javafx(11) 项目,但似乎没有任何效果。我在 IntelliJ IDE 上,例如让我们使用这个项目:https://github.com/EveningSt3r/JFX-hotel-project。 (我在 30 分钟内写了这篇文章,但它很简单并且满足了这个问题的目的)

当我使用 IntelliJ 的 Build Artifacts 功能时:“fx:deploy is not available” 我不知道如何使用 jlink,网上所有的教程都难倒我。 大多数 javafx 教程都是从它是 JDK 的一部分开始的,所以这没有帮助。 我不知道如何使用 Maven 和 Gradle。

这来自一个对 Java 实际工作原理并不十分了解,只知道如何制作东西的家伙。

我已经花了数周时间试图解决这个问题,所以有人可以帮我把它简化到婴儿级别,关于如何将它变成可运行的东西或 exe 吗?我知道我听起来很愚蠢,但我只是累了

【问题讨论】:

  • module-info.java 文件是什么?这不是有效的 Java 限定名称,并且 IntelliJ 不允许创建它......它是如何到达那里的?为什么会在那里?
  • 我正在学习 Tim Buchalka Java 课程。他做到了。这是我定义模块依赖关系的地方,你可以通过右键单击 src 然后选择 new (module-info) 来实现它。没有它我的应用程序无法运行,(我怀疑这是 java 11 的事情)
  • @Chaos_Is_Harmony module-info.java 文件是模块描述符,它是 Java 9 中添加的 Java 平台模块系统 的一部分。任何能够处理 Java 9+ 的 IntelliJ 版本应该理解那个文件。也就是说,不需要模块描述符(尽管使用 JavaFX 可能涉及将 JavaFX 混合放置在模块路径上,而您自己的代码/其他依赖项放置在类路径上)。
  • @Yeetles 您可以使用 Java 14+ 吗?如果是这样,您可能需要查看packaging tool jpackage。如果我没记错的话,它是 Java 14-15 中的一个孵化特性,并在 Java 16 中被标准化。您可能还想查看JPackageScriptFX(我自己从未尝试过,但这里有其他用户推荐)。
  • @Slaw 我回家后试试看。不过有两件事:1:我只需要安装 java 14,我就可以从命令行使用 jpackage,对吗? 2. 你能在理论上把我必须用于这个项目的命令简化吗?本周早些时候,我确实查看了 jpackage 文档,这让我很难过。

标签: java javafx-11


【解决方案1】:

一种选择是使用jpackage 工具。该工具是 Java 14-15 中的一个孵化功能,并在 Java 16 中被标准化。它创建了一个独立的应用程序。换句话说,生成的应用程序不仅包含您自己的代码和任何依赖项,还包含嵌入式 Java 运行时环境 (JRE)。这样,您的最终用户就不必担心安装 Java 或 JavaFX。相反,它们最终会得到一个本机安装程序/可执行文件。

jpackage 有一个 user guide。这个网站上还有一个用户(如果我没记错的话,还有其他用户)创建了一个脚本,这可能会让你的事情变得更简单:JPackageScriptFX


这是一个创建 JavaFX 应用程序的最小示例,其中应用程序使用 jpackage 打包,完全来自命令行。该示例假定一个模块化应用程序(即您的代码和所有依赖项都有一个module-info 文件),但jpackage 也能够打包基于类路径的应用程序(即非模块化应用程序)。

项目结构

├───out
│   ├───classes
│   └───package
└───src
    └───com.example
        │   module-info.java
        │
        └───com
            └───example
                └───app
                        Main.java

请注意,我在名为com.example 的目录下有源代码。这与模块同名,使手动使用javac 更容易(编译模块时)。但是,您不需要这样做。事实上,如果您使用的是 IDE,那么您的源代码可能直接位于 src 下(如果使用 Maven/Gradle,则可能是 src/main/java)。

由于您可能让您的 IDE 编译代码,我建议创建一个名称与模块名称匹配的目录。

源文件

这是module-info.java 文件:

module com.example {
  requires javafx.controls;

  exports com.example.app to javafx.graphics;
}

这是Main.java 文件:

package com.example.app;

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

public class Main extends Application {

  public void start(Stage primaryStage) {
    StackPane root = new StackPane(new Label("Hello, World!"));
    Scene scene = new Scene(root, 500, 300);
    primaryStage.setScene(scene);
    primaryStage.setTitle("JPackage Example");
    primaryStage.show();
  }
}

编译

这是编译上述代码的命令。注意工作目录是项目目录。

javac --module-source-path src --module com.example -d out\classes

我有一个包含 JavaFX 的 JDK。如果不这样做,则需要确保将 JavaFX 放在模块路径上。例如:

javac --module-path <path-to-fx> --module-source-path src --module com.example -d out\classes

但同样,您可能会让 IDE 处理编译。

包装

这是打包现在编译的应用程序的命令。

jpackage --type app-image --name JPackageExample --module-path out/classes --module com.example/com.example.app.Main --dest out/package

--type 确定应用程序类型。在 Windows 上,有三个选项:app-image(我相信所有平台都通用)、exemsi。第一个将简单地创建一个展开的目录(在 Windows 上包含一个 exe 文件)。后两者将为您的应用程序创建 Windows 安装程序。请注意,您必须在 Windows 上才能创建 Windows 软件包(MacOS 和 Linux 相同)。

--module 参数告诉工具主模块和类是什么(即应用程序的入口点)。它的格式是&lt;main-module&gt;[/&lt;main-class&gt;]。如果合适,可以省略主类(例如,您将代码打包到指定了--main-class 的 JAR 文件中)。

同样,我有一个包含 JavaFX 的 JDK。如果您不这样做,请确保在 --module-path 参数中包含 JavaFX 以及您自己的代码。 重要提示:与编译期间不同,如果您将 JavaFX 与 JDK 分开,请确保将 JavaFX JMOD 文件放在模块路径中,不是普通的 JAR 文件;您可以从 Gluon 获取 JMOD 文件(可能与您获得 JavaFX SDK 的地方相同)。请记住,JavaFX 是特定于平台的。


上面的例子完全来自命令行。您可能使用的是 IDE,因此某些步骤可能会有所不同。例如,您可以依靠 IDE 来编译代码,如果需要,可以将其打包到 JAR 文件中。您甚至可以让 IDE 处理调用jpackage,但我不确定。

【讨论】:

  • 我的 JDK 和 IDE 都不支持 JavaFX,但这是一篇非常详细的帖子。太感谢了! IntelliJ 不会让我构建一个用于 --module-path 参数的 Jar,而且我不确定将 JMOD 文件放在哪里。另外,您如何拥有带有 javafx 和使用 jpackage 的 JDK?我认为 jpackage 是 14+ 并且 javafx 从 9 或以下删除
  • 如果您有 JavaFX SDK,那么您可以简单地将 JMOD 文件放在同一位置。但是你把它们放在哪里并不重要,只要你在执行jpackage时将正确的路径传递给--module-path。至于拥有包含 JavaFX 的 JDK,我没有使用 Oracle 发行版。至少有两个其他发行商为 JDK 提供 JavaFX:Bellsoft LibericaAzul Zulu。您必须选择包含 JavaFX 的 JDK 下载。它们(和 Oracle)都基于 OpenJDK,因此它们之间应该没有太大区别。如果需要,检查许可证
  • 请注意,如果您有一个包含 JavaFX 的 JDK,那么 JMOD 文件将被包含并自动使用。顺便说一句,here's an explanation of why you should use the JMOD files 在使用 jpackage 时(注意 jpackage 使用 jlink 创建自定义运行时映像)。
  • JavaFX JDK 将是“Full Liberica JDK”64 位 java 16 对吗?从理论上讲,对 JMOD 文件的需求被删除,我假设此外,我的计算机上使用 Java 16 和 11 不会有我假设的问题。一旦我有了 java 16,IntelliJ 可以自己打包吗?
  • 是的,“Full Liberica JDK”应该是包含 JavaFX 的那个。如果你有那个 JDK,并不是不再需要 JMOD 文件,而是它们包含在 JDK 中并且被隐式使用(就像标准 Java 模块的 JMOD 文件,例如 java.basejava.sql等),这意味着您不必将它们显式添加到 --module-path 参数中。
【解决方案2】:

它与 jlink 无关,仅与您创建工件的方式有关。

每当您在 IntelliJ 中创建 .jar 文件时,在创建工件之前,您必须将 java bin 文件中的文件输入到您的工件中。

为此,您必须转到文件-项目结构-工件。

然后单击加号“+”,将鼠标悬停在 JAR 上并选择 From modules with dependencies。

然后在弹出显示中选择“主类”栏并输入您的主类(可能标题为“主”),然后单击确定。

之后,您将看到一个新框。在该框中单击其中的加号,然后单击“文件”。

然后转到程序文件中的 jre 文件夹,该文件夹位于“Java”文件夹中。进入它,然后双击“bin”。突出显示所有文件,而不是文件夹,然后将其放入您的工件中。

然后在您的工件窗口上单击“确定”,它将关闭。

现在您可以点击“构建工件”按钮了!

单击按钮并选择“构建”

点击按钮后,.jar 文件将出现在您的项目文件夹中的“out”下和“artifacts”中!

祝你有美好的一天! :)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-16
    • 2014-02-16
    • 1970-01-01
    • 2021-03-27
    • 2019-08-09
    • 2011-05-12
    相关资源
    最近更新 更多