为什么不将所有JavaFX deps放在类路径中而又不用担心Java模块呢?

问题描述

我一直在尝试编写Hello JavaFX应用程序,面对着有关启动该应用程序的Java模块的必要考虑。

F.e。 javafx-maven-plugin run 目标产生这样的启动命令:

{col}

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

[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]

如果我正确并正确理解了Packages and Modules规范

    在类路径中定义的
  • 模块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

请问一下有关Java模块的工作原理,我在这里错了吗?

谢谢!

解决方法

警告::尽管下面显示了所需的功能,但将JavaFX模块放在类路径上的方法为not supported。这意味着即使您自己的代码不是模块化的,也应该将JavaFX放在模块路径上。


可以将JavaFX放在类路径上,并完全忽略模块 1 。但是,一个警告是,您的主类不能再分配给javafx.application.Application 2 。解决方法是创建一个单独的主类,该主类仅启动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包含的代码允许您在没有主方法的情况下启动JavaFX应用程序,只要该主类可分配给Application。但是,当它检测到主类可分配给Application时,它将在引导javafx.graphics中检查ModuleLayer -意味着它必须在模块路径上—如果没有,则假定JavaFX丢失。