There are a few answers already posted that could apply partially to your questions, but it might be convenient to collect them here and present them in a full answer.
Application class
In the answer to Maven Shade JavaFX runtime components are missing I explained the reason why, when you use the Application
class as your main class, you are expected to use the module system.
In summary:
As you can read here:
This error comes from sun.launcher.LauncherHelper
in the java.base module (link).
If the main app extends Application
and has a main
method, the LauncherHelper
will check for the javafx.graphics
module to be present as a named module:
Optional<Module> om = ModuleLayer.boot().findModule(JAVAFX_GRAPHICS_MODULE_NAME);
if (!om.isPresent()) {
abort(null, "java.launcher.cls.error5");
}
If that module is not present, the launch is aborted.
Every JavaFX 11 jar has a module-info.class
file, so by definition, these are expected to be added to the module path.
But if you don't run via Application
class, that check is not done.
Main class
This other answer to Different behaviour between Maven & Eclipse to launch a JavaFX 11 app
explains why it works without the modular system when you use a Launcher
class (a Main class not extending Application) with the Maven exec:java
plugin.
In summary:
- Using a Launcher is required to overcome the mentioned
sun.launcher.LauncherHelper
issue.
- Like the maven plugin runs in the classpath, loading all the dependencies into an isolated thread, so does IntelliJ in this case.
If you check the command line when you run Main.main()
:
/path/to/jdk-11.0.2.jdk/Contents/Home/bin/java \
"-javaagent:/Applications/IntelliJ IDEA.app/Contents/lib/idea_rt.jar=60556:/Applications/IntelliJ IDEA.app/Contents/bin" \
-Dfile.encoding=UTF-8 \
-classpath /path/to/so-question-54756176-master/target/classes:/path/to/.m2/repository/org/openjfx/javafx-base/11.0.2/javafx-base-11.0.2.jar:.../path/to/.m2/repository/org/openjfx/javafx-fxml/11.0.2/javafx-fxml-11.0.2-mac.jar \
Main
All the JavaFX jars from the JavaFX SDK are added to the classpath, and you are running the classic java -cp ... Main
.
javafx.fxml missing
These other answer to IntelliJ IDEA - Error: JavaFX runtime components are missing, and are required to run this application explains the error you get when you run on the module system but you don't add javafx.fxml
to the --add-modules
option.
Caused by: java.lang.IllegalAccessError: class com.sun.javafx.fxml.FXMLLoaderHelper (in unnamed module @0x5fce9dc5) cannot access class com.sun.javafx.util.Utils (in module javafx.graphics) because module javafx.graphics does not export com.sun.javafx.util to unnamed module @0x5fce9dc5
at com.sun.javafx.fxml.FXMLLoaderHelper.<clinit>(FXMLLoaderHelper.java:38)
at javafx.fxml.FXMLLoader.<clinit>(FXMLLoader.java:2056)
Your error says that you are using FXML but it can't be resolved in the module-path, so it is trying to access via reflection and that fails since you didn't opened that javafx.graphics
to your unnamed module.
So now you will ask: I didn't set the javafx.graphics
in the first place!
Well, you didn't, but IntelliJ did it for you!
Check the command line when you run MainApp.main()
:
/path/to/jdk-11.0.2.jdk/Contents/Home/bin/java \
--add-modules javafx.base,javafx.graphics \
--add-reads javafx.base=ALL-UNNAMED \
--add-reads javafx.graphics=ALL-UNNAMED \
"-javaagent:/Applications/IntelliJ IDEA.app/Contents/lib/idea_rt.jar=60430:/Applications/IntelliJ IDEA.app/Contents/bin" \
-Dfile.encoding=UTF-8 \
-classpath /path/to/so-question-54756176-master/target/classes:/path/to/.m2/repository/org/openjfx/javafx-base/11.0.2/javafx-base-11.0.2.jar:.../.m2/repository/org/openjfx/javafx-graphics/11.0.2/javafx-graphics-11.0.2-mac.jar \
MainApp
You can see that IntelliJ by default adds javafx.base
and javafx.graphics
. So only the javafx.fxml
is missing (and then you should of course add the module-path).
The recommended solution, as you pointed out, is in the docs:
Either on command line, using --module-path
to include the path to your JavaFX SDK lib folder, and --add-modules
to include javafx.fxml
in this case (where you don't have controls).
Or using the Maven plugin. At some point you will have to leave your IDE, so you will need to use a plugin to run the application.
Maven exec
A final note on the Maven exec
plugin, in case you use it:
What's more, the recommended Maven solution, until the plugin exec:java
is fixed for the modular system (and the good news is that this is being done as we speak), will be using exec:exec
instead, as explained in this issue, so you can specify both vm arguments.