首页 > 解决方案 > 为什么将所有 JavaFX 依赖项放在类路径中而不用担心 Java 模块是不够的?

问题描述

我一直在尝试编写 Hello JavaFX 应用程序,并且面临着需要考虑 Java 模块来启动应用程序。

Fe javafx-maven-plugin运行目标产生这样的启动命令:

[DEBUG] Executing command line: [C:\java\zulu14.29.23-ca-jdk14.0.2-win_x64\bin\java.exe, 
--module-path, C:\.m2\repository\org\openjfx\javafx-base\14\javafx-base-14-win.jar;
C:\.m2\repository\org\openjfx\javafx-base\14\javafx-base-14.jar;
C:\.m2\repository\org\openjfx\javafx-controls\14\javafx-controls-14-win.jar;
C:\.m2\repository\org\openjfx\javafx-controls\14\javafx-controls-14.jar;
C:\.m2\repository\org\openjfx\javafx-graphics\14\javafx-graphics-14-win.jar;
C:\.m2\repository\org\openjfx\javafx-graphics\14\javafx-graphics-14.jar, 
--add-modules, javafx.base,javafx.controls,javafx.graphics, 
-classpath, D:\project\target\classes, org.pkg.pkg.App]

但是我的项目结构没有提到 Java 模块功能——我没有module-info.java文件。
为什么我不能将以上所有 JAR 都放在应用程序类路径中并感到高兴?
铁:

C:\java\zulu14.29.23-ca-jdk14.0.2-win_x64\bin\java.exe 
"-javaagent:C:\Program Files\JetBrains\IntelliJ IDEA 2019.3.4\lib\idea_rt.jar=59556:C:\Program Files\JetBrains\IntelliJ IDEA 2019.3.4\bin" 
-Dfile.encoding=UTF-8 
-classpath D:\project\target\classes;
C:\.m2\repository\org\openjfx\javafx-controls\14\javafx-controls-14.jar;
C:\.m2\repository\org\openjfx\javafx-controls\14\javafx-controls-14-win.jar;
C:\.m2\repository\org\openjfx\javafx-graphics\14\javafx-graphics-14.jar;
C:\.m2\repository\org\openjfx\javafx-graphics\14\javafx-graphics-14-win.jar;
C:\.m2\repository\org\openjfx\javafx-base\14\javafx-base-14.jar;
C:\.m2\repository\org\openjfx\javafx-base\14\javafx-base-14-win.jar 
org.pkg.pkg.App

如果我是对的并且正确理解包和模块规范

但我得到一个错误

Error: JavaFX runtime components are missing, and are required to run this application

有人可以解释一下我在哪里错了,关于 Java 模块是如何工作的吗?

提前致谢!

标签: javamavenjavafxjava-platform-module-system

解决方案


警告:尽管下面显示了您想要的可能,但不支持将 JavaFX 模块放在类路径上。这意味着您应该将 JavaFX 放在模块路径上,即使您自己的代码是非模块化的。


可以将 JavaFX 放在类路径上并完全忽略模块1。但是,需要注意的是,您的主类不能再分配给javafx.application.Application2。解决方法是创建一个单独的主类来简单地启动 JavaFX 应用程序。例如:

import javafx.application.Application;

public class Launcher {

  public static void main(String[] args) {
    // where YourApp.class is replaced with your Application class
    Application.launch(YourApp.class, args);
  }
}

1. 你不能完全忽略模块。类路径上的所有代码最终都在未命名的模块中,并且运行时映像中的所有模块(即 JDK/JRE)仍然作为命名模块运行。

2. 这是由于一个实现细节。Java 包含允许您在没有 main 方法的情况下启动 JavaFX 应用程序的代码,只要 main 类可分配给Application. 但是,当它检测到主类可分配给它时,它会在引导中Application进行检查——这意味着它必须在模块路径上——如果不存在,则假定 JavaFX 缺失。javafx.graphicsModuleLayer


推荐阅读