Why isn't it enough put all JavaFX deps in the classpath w/o bothering about Java modules?

陌路散爱 提交于 2020-12-07 18:08:06

问题


I've been trying to write Hello JavaFX app and faced with necessity consider about Java modules for starting the app.

F.e. javafx-maven-plugin's run goal produce such startup command:

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

But my project's structure doesn't mention Java module functionality - I didn't have module-info.java file.
Why can't I put all above JARs in the app classpath and be happy?
F.e.:

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

If I'm right and understand Packages and Modules spec correctly

  • module JARs defined in the classpath treated as unnamed modules
  • unnamed modules export all their packages, i.e. everything is visible in them

But I get an error

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

Could someoune please explain me where I'm wrong here, about how Java modules work?

Thanks in advance!


回答1:


Warning: Although the below shows what you want is possible, placing the JavaFX modules on the class-path is not supported. This means you should place JavaFX on the module-path, even when your own code is non-modular.


You can put JavaFX on the class-path and completely ignore modules1. However, the one caveat is that your main class can no longer be assignable to javafx.application.Application2. The workaround is to create a separate main class that simply launches the JavaFX application. For example:

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. Your can't really ignore modules completely. All code on the class-path ends up in the unnamed module and all the modules in the run-time image (i.e. the JDK/JRE) still function as named modules.

2. This is due to an implementation detail. Java contains code which allows you to launch JavaFX applications without a main method, so long as the main class is assignable to Application. But when it detects that the main class is assignable to Application it checks for javafx.graphics in the boot ModuleLayer—meaning it must be on the module-path—and if not there then it assumes JavaFX is missing.



来源:https://stackoverflow.com/questions/63425176/why-isnt-it-enough-put-all-javafx-deps-in-the-classpath-w-o-bothering-about-jav

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!