问题
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.Application
2. 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