90

I'm having trouble getting IntellJ to recognize JavaFX packages. With a new JavaFX project, with OpenJDK 11, when trying to build the project, IntelliJ can't recognize the JavaFX packages.

I've imported openjfx:javafx-base-11 from the Maven repo.

I've looked at other questions and the solutions seem to range from checking that the bytecode is at the right level (mine is), and that the project language is correct (mine is).

Anyone have any ideas?

pic 1

pic 2

pic 3

Edit:

Error:

enter image description here

0xCursor
  • 2,224
  • 4
  • 13
  • 30
AlwaysNeedingHelp
  • 1,509
  • 1
  • 17
  • 24
  • can you try from terminal to compile and run? – drowny Sep 23 '18 at 15:35
  • You'll need to require its module(s) in your `module-info.java` – Jacob G. Sep 23 '18 at 15:36
  • I think you need this artifact: https://mvnrepository.com/artifact/org.openjfx/javafx/11 the base one doesn't contain everything I guess. – Jorn Vernee Sep 23 '18 at 15:36
  • @JornVernee when I try that I get an error. I edited the OP with it. – AlwaysNeedingHelp Sep 23 '18 at 15:41
  • @JacobG. how do I go about this? I have not used the module system before. I was told that you don't require a modulized application to use javaFX11. Is this wrong? – AlwaysNeedingHelp Sep 23 '18 at 15:41
  • 1
    Whoever told you that was likely mistaken. You need to create a `module-info.java` file in your source folder and explicitly require whichever JavaFX modules that you're using: `requires javafx.controls;`, `requires javafx.graphics;`, etc. – Jacob G. Sep 23 '18 at 15:51
  • Hmm still nothing is working. This is a little frustrating. I also tried a gradle build and set the javafx artifact as a dependency and that still wouldn't work. It might be something small I'm missing, does anyone have a simple hello world javafx application that they can host and I can look at? – AlwaysNeedingHelp Sep 23 '18 at 16:17
  • @AlwaysNeedingHelp can you let me know how to get the Project Level Language drop down list (below Project SDK) to show '11-Local Variable Syntax for lambda parameters' in Intellij as per the screenshot you have posted? – iCoder Sep 30 '18 at 04:13
  • @Slaw thanks after I upgraded Intellij was able to find it in the drop-down list. – iCoder Sep 30 '18 at 10:26
  • Check the local .m2 whether the jar got downloaded or not in the location –  Sep 23 '18 at 15:46
  • We were having this error: `java.lang.IllegalAccessError: class com.sun.javafx.fxml.FXMLLoaderHelper (in unnamed module ...) cannot access class com.sun.javafx.util.Utils (in module javafx.graphics) because module javafx.graphics does not export com.sun.javafx.util` . The reason was that we were running the Application class directly without `Application.launch`. Shared here as it is might be useful. – lepe Jul 18 '19 at 01:50
  • I got the same issue when I moved to java11 but when I got back to java 8 everything worked fine – Chris Claude Sep 25 '19 at 17:34
  • I managed to make mine worked by unchecked the read only of the windows folder containing javafx. It worked for me, might give it a try – Mark Jun 21 '20 at 00:24

5 Answers5

150

As mentioned in the comments, the Starting Guide is the place to start with Java 11 and JavaFX 11.

The key to work as you did before Java 11 is to understand that:

  • JavaFX 11 is not part of the JDK anymore
  • You can get it in different flavors, either as an SDK or as regular dependencies (maven/gradle).
  • You will need to include it to the module path of your project, even if your project is not modular.

JavaFX project

If you create a regular JavaFX default project in IntelliJ (without Maven or Gradle) I'd suggest you download the SDK from here. Note that there are jmods as well, but for a non modular project the SDK is preferred.

These are the easy steps to run the default project:

  1. Create a JavaFX project
  2. Set JDK 11 (point to your local Java 11 version)
  3. Add the JavaFX 11 SDK as a library. The URL could be something like /Users/<user>/Downloads/javafx-sdk-11/lib/. Once you do this you will notice that the JavaFX classes are now recognized in the editor.

JavaFX 11 Project

  1. Before you run the default project, you just need to add these to the VM options:

    --module-path /Users/<user>/Downloads/javafx-sdk-11/lib --add-modules=javafx.controls,javafx.fxml

  2. Run

Maven

If you use Maven to build your project, follow these steps:

  1. Create a Maven project with JavaFX archetype
  2. Set JDK 11 (point to your local Java 11 version)
  3. Add the JavaFX 11 dependencies.

    <dependencies>
        <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-controls</artifactId>
            <version>11</version>
        </dependency>
        <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-fxml</artifactId>
            <version>11</version>
        </dependency>
    </dependencies>
    

Once you do this you will notice that the JavaFX classes are now recognized in the editor.

JavaFX 11 Maven project

You will notice that Maven manages the required dependencies for you: it will add javafx.base and javafx.graphics for javafx.controls, but most important, it will add the required classifier based on your platform. In my case, Mac.

This is why your jars org.openjfx:javafx-controls:11 are empty, because there are three possible classifiers (windows, linux and mac platforms), that contain all the classes and the native implementation.

In case you still want to go to your .m2 repo and take the dependencies from there manually, make sure you pick the right one (for instance .m2/repository/org/openjfx/javafx-controls/11/javafx-controls-11-mac.jar)

  1. Replace default maven plugins with those from here.

  2. Run mvn compile javafx:run, and it should work.

Similar works as well for Gradle projects, as explained in detail here.

EDIT

The mentioned Getting Started guide contains updated documentation and sample projects for IntelliJ:

jewelsea
  • 130,119
  • 12
  • 333
  • 365
José Pereda
  • 39,900
  • 6
  • 84
  • 114
  • I am having trouble with JavaFX Project Step 3. Project Structure -> Project Settings -> Libraries -> + (New Project Library) -> Java. Then input path to javafx-sdk-11, correct? Then, "IDEA cannot determine what kind of files the chosen items contain. Choose the appropriate categories from the list." – Jack J Oct 06 '18 at 19:24
  • 1
    Path is something like `/Users//Downloads/javafx-sdk-11/lib/`, notice the `lib` folder. That should contain all the javafx jars – José Pereda Oct 06 '18 at 19:26
  • 5
    If anyone is having issues with the module path it needs to look something like this on windows: --module-path="C:\Path\To\Your\JavaFX\lib" --add-modules=javafx.controls,javafx.fxml,javafx.base,javafx.media,javafx.graphics,javafx.swing,javafx.web Notice the "=" and also the quotes around it. This worked for me while any other approach didn't. Furthermore keep in mind that the -jar YourJar.jar parameter needs to come AFTER the module path and add-modules options. – Jalau Oct 25 '18 at 10:58
  • Very cool. Has anyone managed to get the install artifact working? – sproketboy Nov 09 '18 at 18:17
  • 4
    Hi @JoséPereda. I've been struggling with this guide since a while, but I can't really make IntelliJ run my code, even if I've done exactly what you've written. I'm still getting "Error:java: module not found: javafx.fxml" and so on. Any chance to have a private chat to help me out sort out this issue? Thank you. – Davide3i Dec 22 '18 at 17:22
  • 1
    @jalau thank you! the quotes actually did it, you should write this as an answer. – derfect Jan 18 '19 at 15:54
  • When I create a new JavaFX project it works, but it doesn't for existing projects – Rainb Feb 01 '19 at 10:54
  • Last line solved my issue with intellij + javafx 11 + gradle 5 ty <3. – mojtab23 Apr 21 '19 at 19:19
  • I try the maven way but when I exec:java I get following error: The parameters 'mainClass' for goal org.codehaus.mojo:exec-maven-plugin:1.6.0:java are missing or invalid. I set mainClass to 'package.ClassThatExtendsApplicationIncludingMainMethod' any idea whats missing? – Zuop Jun 05 '19 at 21:51
  • 2
    When I build the distribution for the sample project for Gradle and then run it, I get the error message: "Error: JavaFX runtime components are missing, and are required to run this application" – Trejkaz Jun 23 '19 at 06:55
  • I have applied this and especially the improvement suggested by @Jalau but I get the following ---> Error occurred during initialization of boot layer java.lang.module.FindException: Module javafx.swing not found. Some help please – Chris Claude Sep 25 '19 at 17:08
  • remember about runtime jbrsdk8 and java 8 compatibility for java 11 and jfoenix https://stackoverflow.com/a/58331582/602018 – 42n4 Oct 10 '19 at 22:17
  • How to do Step 4 (adding VM options) in IntelliJ can be found here: https://stackoverflow.com/a/50938399/2386040 – Jan Apr 08 '20 at 11:55
  • I was able to add the VM options on IntelliJ as described above on my Debian Buster system. Debian provides a .deb install for JavaFX. I inserted the path where Synaptic installed the JavaFX on my system, which is /usr/share/openjfx/lib. I was able to run the default IntelliJ JavaFX sample program. – Forever Learing Programming Dec 15 '20 at 22:17
12

The issue that JavaFX is no longer part of JDK 11. The following solution works using IntelliJ (haven't tried it with NetBeans):

  1. Add JavaFX Global Library as a dependency:

    Settings -> Project Structure -> Module. In module go to the Dependencies tab, and click the add "+" sign -> Library -> Java-> choose JavaFX from the list and click Add Selected, then Apply settings.

  2. Right click source file (src) in your JavaFX project, and create a new module-info.java file. Inside the file write the following code :

    module YourProjectName { 
        requires javafx.fxml;
        requires javafx.controls;
        requires javafx.graphics;
        opens sample;
    }
    

    These 2 steps will solve all your issues with JavaFX, I assure you.

Reference : There's a You Tube tutorial made by The Learn Programming channel, will explain all the details above in just 5 minutes. I also recommend watching it to solve your problem: https://www.youtube.com/watch?v=WtOgoomDewo

M. S.
  • 3,461
  • 10
  • 22
  • 33
Coder992
  • 169
  • 1
  • 10
7

None of the above worked for me. I spent too much time clearing other errors that came up. I found this to be the easiest and the best way.

This works for getting JavaFx on Jdk 11, 12 & on OpenJdk12 too!

  • The Video shows you the JavaFx Sdk download
  • How to set it as a Global Library
  • Set the module-info.java (i prefer the bottom one)

module thisIsTheNameOfYourProject {
    requires javafx.fxml;
    requires javafx.controls;
    requires javafx.graphics;
    opens sample;
}

The entire thing took me only 5mins !!!

Yo Apps
  • 448
  • 9
  • 8
5

Quick summary, you can do either:

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

OR

  1. 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 that 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 the 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 Run button in the top toolbar of IDE to run your application class directly, you instead:

  1. Went to the Maven window on 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 that 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.

M.P.B
  • 9
  • 4
jewelsea
  • 130,119
  • 12
  • 333
  • 365
0

A very good explanation can be found at

https://edencoding.com/runtime-components-error/

including

  1. Giving reflective access to your module

  2. Giving other access to your module

and total, we need, adding to the above answers, add exports to your module definition

module my.project {
    requires javafx.fxml;
    requires javafx.controls;
    opens my.project to javafx.graphics;
    exports my.project;
}
WebComer
  • 969
  • 14
  • 27