[java] IntelliJ can't recognize JavaFX 11 with OpenJDK 11

Quick summary, you can do either:

  1. Include the JavaFX modules via --module-path and --add-modules like in José's answer.

    OR

  2. Once you have JavaFX libraries added to your project (either manually or via maven/gradle import), add the module-info.java file similar to the one specified in this answer. (Note that this solution makes your app modular, so if you use other libraries, you will also need to add statements to require their modules inside the module-info.java file).


This answer is a supplement to Jose's answer.

The situation is this:

  1. You are using a recent Java version, e.g. 13.
  2. You have a JavaFX application as a Maven project.
  3. In your Maven project you have the JavaFX plugin configured and JavaFX dependencies setup as per Jose's answer.
  4. You go to the source code of your main class which extends Application, you right-click on it and try to run it.
  5. You get an IllegalAccessError involving an "unnamed module" when trying to launch the app.

Excerpt for a stack trace generating an IllegalAccessError when trying to run a JavaFX app from Intellij Idea:

Exception in Application start method
java.lang.reflect.InvocationTargetException
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:567)
    at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:464)
    at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:363)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:567)
    at java.base/sun.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:1051)
Caused by: java.lang.RuntimeException: Exception in Application start method
    at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:900)
    at javafx.graphics/com.sun.javafx.application.LauncherImpl.lambda$launchApplication$2(LauncherImpl.java:195)
    at java.base/java.lang.Thread.run(Thread.java:830)
Caused by: java.lang.IllegalAccessError: class com.sun.javafx.fxml.FXMLLoaderHelper (in unnamed module @0x45069d0e) 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 @0x45069d0e
    at com.sun.javafx.fxml.FXMLLoaderHelper.<clinit>(FXMLLoaderHelper.java:38)
    at javafx.fxml.FXMLLoader.<clinit>(FXMLLoader.java:2056)
    at org.jewelsea.demo.javafx.springboot.Main.start(Main.java:13)
    at javafx.graphics/com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$9(LauncherImpl.java:846)
    at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runAndWait$12(PlatformImpl.java:455)
    at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$10(PlatformImpl.java:428)
    at java.base/java.security.AccessController.doPrivileged(AccessController.java:391)
    at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$11(PlatformImpl.java:427)
    at javafx.graphics/com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:96)
Exception running application org.jewelsea.demo.javafx.springboot.Main

OK, now you are kind of stuck and have no clue what is going on.

What has actually happened is this:

  1. Maven has successfully downloaded the JavaFX dependencies for your application, so you don't need to separately download the dependencies or install a JavaFX SDK or module distribution or anything like that.
  2. Idea has successfully imported the modules as dependencies to your project, so everything compiles OK and all of the code completion and everything works fine.

So it seems everything should be OK. BUT, when you run your application, the code in the JavaFX modules is failing when trying to use reflection to instantiate instances of your application class (when you invoke launch) and your FXML controller classes (when you load FXML). Without some help, this use of reflection can fail in some cases, generating the obscure IllegalAccessError. This is due to a Java module system security feature which does not allow code from other modules to use reflection on your classes unless you explicitly allow it (and the JavaFX application launcher and FXMLLoader both require reflection in their current implementation in order for them to function correctly).

This is where some of the other answers to this question, which reference module-info.java, come into the picture.

So let's take a crash course in Java modules:

The key part is this:

4.9. Opens

If we need to allow reflection of private types, but we don't want all of our code exposed, we can use the opens directive to expose specific packages.

But remember, this will open the package up to the entire world, so make sure that is what you want:

module my.module { opens com.my.package; }

So, perhaps you don't want to open your package to the entire world, then you can do:

4.10. Opens … To

Okay, so reflection is great sometimes, but we still want as much security as we can get from encapsulation. We can selectively open our packages to a pre-approved list of modules, in this case, using the opens…to directive:

module my.module { opens com.my.package to moduleOne, moduleTwo, etc.; }

So, you end up creating a src/main/java/module-info.java class which looks like this:

module org.jewelsea.demo.javafx.springboot {
    requires javafx.fxml;
    requires javafx.controls;
    requires javafx.graphics;
    opens org.jewelsea.demo.javafx.springboot to javafx.graphics,javafx.fxml;
}

Where, org.jewelsea.demo.javafx.springboot is the name of the package which contains the JavaFX Application class and JavaFX Controller classes (replace this with the appropriate package name for your application). This tells the Java runtime that it is OK for classes in the javafx.graphics and javafx.fxml to invoke reflection on the classes in your org.jewelsea.demo.javafx.springboot package. Once this is done, and the application is compiled and re-run things will work fine and the IllegalAccessError generated by JavaFX's use of reflection will no longer occur.

But what if you don't want to create a module-info.java file

If instead of using the the Run button in the top toolbar of IDE to run your application class directly, you instead:

  1. Went to the Maven window in the side of the IDE.
  2. Chose the javafx maven plugin target javafx.run.
  3. Right-clicked on that and chose either Run Maven Build or Debug....

Then the app will run without the module-info.java file. I guess this is because the maven plugin is smart enough to dynamically include some kind of settings which allows the app to be reflected on by the JavaFX classes even without a module-info.java file, though I don't know how this is accomplished.

To get that setting transferred to the Run button in the top toolbar, right-click on the javafx.run Maven target and choose the option to Create Run/Debug Configuration for the target. Then you can just choose Run from the top toolbar to execute the Maven target.

Examples related to java

Under what circumstances can I call findViewById with an Options Menu / Action Bar item? How much should a function trust another function How to implement a simple scenario the OO way Two constructors How do I get some variable from another class in Java? this in equals method How to split a string in two and store it in a field How to do perspective fixing? String index out of range: 4 My eclipse won't open, i download the bundle pack it keeps saying error log

Examples related to intellij-idea

IntelliJ: Error:java: error: release version 5 not supported Has been compiled by a more recent version of the Java Runtime (class file version 57.0) Error: Java: invalid target release: 11 - IntelliJ IDEA IntelliJ can't recognize JavaFX 11 with OpenJDK 11 Error: JavaFX runtime components are missing, and are required to run this application with JDK 11 ERROR Source option 1.5 is no longer supported. Use 1.6 or later Cannot inline bytecode built with JVM target 1.8 into bytecode that is being built with JVM target 1.6 How to configure "Shorten command line" method for whole project in IntelliJ intellij idea - Error: java: invalid source release 1.9 Failed to resolve: com.google.android.gms:play-services in IntelliJ Idea with gradle

Examples related to javafx

IntelliJ can't recognize JavaFX 11 with OpenJDK 11 Error: JavaFX runtime components are missing, and are required to run this application with JDK 11 JavaFX FXML controller - constructor vs initialize method Why is JavaFX is not included in OpenJDK 8 on Ubuntu Wily (15.10)? cannot resolve symbol javafx.application in IntelliJ Idea IDE javac: invalid target release: 1.8 How to change the color of text in javafx TextField? Issue with background color in JavaFX 8 What's the location of the JavaFX runtime JAR file, jfxrt.jar, on Linux? How to create a popup windows in javafx

Examples related to java-11

Error: Java: invalid target release: 11 - IntelliJ IDEA How to install OpenJDK 11 on Windows? How to install JDK 11 under Ubuntu? Java 11 package javax.xml.bind does not exist IntelliJ can't recognize JavaFX 11 with OpenJDK 11 Unable to compile simple Java 10 / Java 11 project with Maven Java: How to resolve java.lang.NoClassDefFoundError: javax/xml/bind/JAXBException

Examples related to javafx-11

IntelliJ can't recognize JavaFX 11 with OpenJDK 11