“Error: JavaFX runtime components are missing, and are required to run this application” means the java command started a class that extends JavaFX's Applicationwithout JavaFX's modules on the module path, usually because JavaFX's jar files were put on the classpath instead. You fix it by loading JavaFX as modules: run the program through the JavaFX plugin for Maven or Gradle, add two flags to the java command, or use a JDK that already contains JavaFX. Every fix below is for JavaFX 27 on Java 25.
Here is a complete JavaFX program, and the commands that compile and run it with the JavaFX SDK (fix 3 below) on macOS or Linux:
import javafx.application.Application;import javafx.scene.Scene;import javafx.scene.control.Label;import javafx.scene.layout.StackPane;import javafx.stage.Stage; public class HelloApp extends Application { @Override public void start(Stage stage) { Label label = new Label("Hello, JavaFX"); stage.setScene(new Scene(new StackPane(label), 320, 120)); stage.setTitle("Hello"); stage.show(); } public static void main(String[] args) { launch(args); }}A window titled "Hello", 320 by 120 pixels, with the words "Hello, JavaFX" in the middle. Close it and the program ends.
$ export PATH_TO_FX=$HOME/javafx-sdk-27/lib$ javac --module-path $PATH_TO_FX --add-modules javafx.controls HelloApp.java$ java --enable-native-access=javafx.graphics --module-path $PATH_TO_FX --add-modules javafx.controls HelloAppWhat the error means#
The java command makes one extra check before it starts a program. If the main class extends javafx.application.Application, directly or through a parent class, it looks for JavaFX's javafx.graphics module among the loaded modules. (Since Java 9, the JDK is split into named modules, and JavaFX ships its jar files as modules too: each one declares a name and the packages it shares.) If that module is not loaded, java stops with the message before your main method runs.
A jar on the classpath, the plain list of folders and jars where Java finds classes, is never loaded as a named module, so JavaFX on the classpath does not count. That is the usual cause: Maven, Gradle and IDE libraries put every dependency on the classpath unless told otherwise. When JavaFX is missing altogether, the message is a different one. Both cases, from a terminal:
$ java -cp ".:$PATH_TO_FX/*" HelloAppError: JavaFX runtime components are missing, and are required to run this application$ java HelloAppError: Could not find or load main class HelloAppCaused by: java.lang.NoClassDefFoundError: javafx/application/ApplicationIn the first command, JavaFX's jars are on the classpath. Java can load HelloApp and see that its parent class is Application, but it finds no javafx.graphics module. In the second, JavaFX is nowhere, so Java cannot even load HelloApp. The cure is the same for both.
Key ideaJavaFX has to be loaded as modules: found through --module-path and named with --add-modules. On the classpath, it gives the runtime components error.
Why JavaFX is not included in the JDK#
JavaFX 8 shipped inside Oracle's JDK 8. In March 2018 Oracle announced that, starting with JDK 11, JavaFX would be a separate download, decoupled from the JDK, and named the module system added in Java 9 as what made the split practical. Since then JavaFX has been developed as OpenJFX, an OpenJDK project with its own release every six months. JavaFX 27, the current release, needs JDK 25 or later.
So Oracle JDK 25 and the usual OpenJDK builds, such as Eclipse Temurin, have no JavaFX: you bring it yourself. The SDK is a download linked from openjfx.io, and Maven and Gradle fetch JavaFX from Maven Central, where it is published under the group org.openjfx. The story of AWT, Swing and JavaFX is in the JavaFX overview.
Fix 1: Maven and the JavaFX Maven plugin#
In a Maven project, JavaFX is an ordinary dependency, and the JavaFX Maven plugin starts the program with the module flags. With HelloApp in the package com.example, the pom.xml needs:
<properties> <maven.compiler.release>25</maven.compiler.release></properties> <dependencies> <dependency> <groupId>org.openjfx</groupId> <artifactId>javafx-controls</artifactId> <version>27</version> </dependency></dependencies> <build> <plugins> <plugin> <groupId>org.openjfx</groupId> <artifactId>javafx-maven-plugin</artifactId> <version>0.0.8</version> <configuration> <mainClass>com.example.HelloApp</mainClass> <options> <option>--enable-native-access=javafx.graphics</option> </options> </configuration> </plugin> </plugins></build>javafx-controls brings javafx-graphics and javafx-base with it, and Maven downloads the files built for your operating system. Add javafx-fxml as well if you use FXML. mainClass names your class, and each option is passed to java; this one silences the warnings explained in fix 3. Then run:
$ mvn javafx:runThe plugin starts java with --module-path and --add-modules for the JavaFX jars, and the window opens. A project with the Maven wrapper runs ./mvnw javafx:run instead. The details of the pom.xml are in Maven and Gradle.
module-info.java file, an IDE's Run arrow next to main starts java with every dependency on the classpath, JavaFX included, and the error comes back. Run the javafx:run goal instead. In IntelliJ IDEA it is in the Maven tool window, under Plugins, javafx.Fix 2: Gradle and the JavaFX Gradle plugin#
Gradle has a plugin of its own, org.openjfx.javafxplugin. In build.gradle.kts:
plugins { application id("org.openjfx.javafxplugin") version "0.1.0"} repositories { mavenCentral()} javafx { version = "27" modules("javafx.controls")} application { mainClass = "com.example.HelloApp" applicationDefaultJvmArgs = listOf("--enable-native-access=javafx.graphics")}The javafx block picks the JavaFX version and modules, and the plugin adds the matching jars for your operating system. When you run ./gradlew run (gradlew run on Windows), the plugin moves those jars from the classpath to the module path and adds --add-modules. In a Groovy build.gradle, the same block reads modules = [ 'javafx.controls' ], and the plugin line is id 'org.openjfx.javafxplugin' version '0.1.0'. As with Maven, start the program with the Gradle run task, not with the Run arrow next to main.
Fix 3: the JavaFX SDK with --module-path and --add-modules#
Without a build tool, download the JavaFX 27 SDK for your operating system and processor (aarch64 on an Apple Silicon Mac) and unzip it. Its libfolder holds JavaFX's modules as jar files. Both javac and java need to be told about it, as in the commands at the top of this page. These are the same on Linux, Ubuntu included. In the Windows Command Prompt:
set PATH_TO_FX="C:\Program Files\javafx-sdk-27\lib"javac --module-path %PATH_TO_FX% --add-modules javafx.controls HelloApp.javajava --enable-native-access=javafx.graphics --module-path %PATH_TO_FX% --add-modules javafx.controls HelloApp--module-pathsays where the modules are: the SDK'slibfolder, not the SDK folder above it. Both commands need it.--add-modules javafx.controlssays which modules to load.javafx.controlsbringsjavafx.graphicsandjavafx.base; list more with commas, as injavafx.controls,javafx.fxml. Both commands need it.--enable-native-access=javafx.graphicsis forjavaonly. Since JDK 24 the JVM prints warnings when a module loads native code (code compiled for your system, which JavaFX uses to draw) without permission, and the JavaFX 24 release notes ask applications to grant it. Addjavafx.mediaandjavafx.webto the list if you use them.
%PATH_TO_FX% works in the Command Prompt only. In PowerShell, write the path out in full, in quotes, in both commands.
In IntelliJ IDEA, Eclipse, VS Code and NetBeans#
An IDE needs the same flags, entered once in the run configuration. They go in the VM options, the settings for the JVM itself. Program arguments are a different box: what you type there reaches your main method in args, and the error stays.
--module-path /path/to/javafx-sdk-27/lib --add-modules javafx.controls --enable-native-access=javafx.graphics- IntelliJ IDEA: Run, Edit Configurations, then Modify options, Add VM options. Add the
libfolder under File, Project Structure, Libraries too, so the editor can compile the imports. - Eclipse: Run, Run Configurations, your Java Application, the Arguments tab, VM arguments.
- NetBeans: the project's Properties, Run, VM Options.
- VS Code:
vmArgsin.vscode/launch.json, as below, then run with F5.
{ "version": "0.2.0", "configurations": [ { "type": "java", "name": "HelloApp", "request": "launch", "mainClass": "HelloApp", "vmArgs": "--module-path \"C:/Program Files/javafx-sdk-27/lib\" --add-modules javafx.controls --enable-native-access=javafx.graphics" } ]}On Windows, a path with a space goes in quotes, and forward slashes work in Java paths, which spares you escaping backslashes in JSON. Every flag is explained in Writing, compiling and running a JavaFX application.
Fix 4: a JDK that includes JavaFX#
Some vendors build a JDK with JavaFX inside, among them BellSoft (the Full JDK package of Liberica JDK) and Azul (the JDK FX package of Zulu). There, JavaFX's modules are part of the runtime, so plain javac HelloApp.java and java HelloApp work with no module path. To check a JDK, run java --list-modules: with JavaFX built in, javafx.controls is in the list. Make sure your IDE runs the program on that JDK too.
The launcher class workaround, and why it is only a workaround#
Many answers online suggest a second main class that does not extend Application:
public class Launcher { public static void main(String[] args) { HelloApp.main(args); }}Start Launcher instead of HelloApp and the error disappears, because java only checks the class it starts. JavaFX is still on the classpath, though, and JavaFX does not support being loaded from there. When it starts, it logs a warning that begins Unsupported JavaFX configuration: classes were loaded from 'unnamed module @, followed by a number that changes on every run. The window usually opens, but on a setup JavaFX does not support, so keep this for the cases that need it, such as one jar that holds every dependency. Fixes 1 to 4 load JavaFX the supported way.
Related errors and what each one means#
| What you see | What it means | Fix |
|---|---|---|
Error: JavaFX runtime components are missing, and are required to run this application, from java | JavaFX's jars are on the classpath, put there by Maven, Gradle or an IDE library, and the main class extends Application. | Start with mvn javafx:run or ./gradlew run, or give java the module flags. |
Error: Could not find or load main class HelloApp and Caused by: java.lang.NoClassDefFoundError: javafx/application/Application, from java | JavaFX is not there at all: java ran without --module-path and --add-modules (often after javac had them), or with --module-path but no --add-modules. | Give java both flags, the same as javac. |
error: package javafx.application does not exist, from javac, with an error for each JavaFX class you use | javac cannot see JavaFX: the module flags are missing from the javac command. | Add --module-path and --add-modules javafx.controls to javac. |
Error occurred during initialization of boot layer and java.lang.module.FindException: Module javafx.controls not found (from javac: error: module not found: javafx.controls) | The module path points at the wrong folder, usually the SDK folder instead of its lib folder, or the path is mistyped, or PATH_TO_FX was set in a different terminal. | Point --module-path at javafx-sdk-27/lib, and check the variable with echo $PATH_TO_FX (echo %PATH_TO_FX% on Windows). |
WARNING: A restricted method in java.lang.System has been called and three more WARNING lines; the window still opens | JDK 24 and newer warn when a module loads native code without permission. | Add --enable-native-access=javafx.graphics to java, as one of the warning lines suggests. |
Checklist#
- 1
java -versionreports 25 or newer, since JavaFX 27 needs JDK 25. - 2With Maven or Gradle, the program starts through
mvn javafx:runor./gradlew run, not the Run arrow next tomain. - 3With the SDK,
javacandjavaboth get--module-pathpointing at thelibfolder and--add-modulesnaming every JavaFX module you import. - 4
javaalso gets--enable-native-access=javafx.graphics. - 5In an IDE, the flags sit in the VM options of the run configuration, not in program arguments.
Questions people ask#
- How do I fix “JavaFX runtime components are missing” in IntelliJ IDEA?
- In a Maven or Gradle project, start the program through the build tool instead of the Run arrow next to
main: run thejavafx:rungoal from the Maven tool window, or the Gradleruntask. With the JavaFX SDK, open Run, Edit Configurations, choose Modify options, Add VM options, and enter--module-path /path/to/javafx-sdk-27/lib --add-modules javafx.controls. - Why do I get this error with Maven or Gradle?
- Running the main class directly puts JavaFX's jar files on the classpath, and the
javalauncher accepts JavaFX only as modules when the main class extendsApplication.mvn javafx:runand./gradlew runwith the JavaFX plugin put JavaFX on the module path for you. - Why is JavaFX not included in the JDK?
- In March 2018 Oracle announced that, starting with JDK 11, JavaFX would be a separate download, decoupled from the JDK, a split that the module system of Java 9 made practical. JavaFX is now developed as OpenJFX, an OpenJDK project with releases of its own.
- Does Java 25 have JavaFX?
- No. JDK 25 builds such as Oracle JDK and Eclipse Temurin do not contain JavaFX, so you add it with Maven, Gradle or the JavaFX SDK, and JavaFX 27 needs JDK 25 or later. Some vendors ship a JDK with JavaFX inside, such as BellSoft's Liberica Full JDK and Azul's Zulu JDK FX.
- Is JavaFX still used today?
- Yes. JavaFX is developed in the open as OpenJFX, with a new release about every six months (JavaFX 27 is the current one), and Oracle's Java roadmap says it keeps releasing JavaFX through that project. It is used for desktop applications on Windows, macOS and Linux.