26

This question is likely about the same issue as this one, but it appears the asker of that one hasn't added enough information to receive a helpful response.

I am trying to run a JavaFx application with JDK and JavaFx SDK version 11.0.2.

This code works exactly as expected, producing an empty window:

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

public class Main extends Application {

    public void start(Stage primaryStage) throws Exception {
        StackPane root = new StackPane();
        primaryStage.setScene(new Scene(root, 420, 420));
        primaryStage.show();
    }


    public static void main(String[] args) {
        launch(args);
    }
}

However, if I try to add a label to the StackPane, an exception is thrown.

import ...
import javafx.scene.control.Label;

public class Main extends Application {

    public void start(Stage primaryStage) throws Exception {
        StackPane root = new StackPane();
        root.getChildren().add(new Label("42"));
        primaryStage.setScene(new Scene(root, 420, 420));
        primaryStage.show();
    }


    public static void main(String[] args) {
        launch(args);
    }
}

The stack trace it produces looks like this (line 13 in Main is where the Label is created):

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:566)
    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:566)
    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:834)
Caused by: java.lang.IllegalAccessError: superclass access check failed: class com.sun.javafx.scene.control.ControlHelper (in unnamed module @0xbbd2743) cannot access class com.sun.javafx.scene.layout.RegionHelper (in module javafx.graphics) because module javafx.graphics does not export com.sun.javafx.scene.layout to unnamed module @0xbbd2743
    at java.base/java.lang.ClassLoader.defineClass1(Native Method)
    at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1016)
    at java.base/java.security.SecureClassLoader.defineClass(SecureClassLoader.java:174)
    at java.base/jdk.internal.loader.BuiltinClassLoader.defineClass(BuiltinClassLoader.java:802)
    at java.base/jdk.internal.loader.BuiltinClassLoader.findClassOnClassPathOrNull(BuiltinClassLoader.java:700)
    at java.base/jdk.internal.loader.BuiltinClassLoader.loadClassOrNull(BuiltinClassLoader.java:623)
    at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:581)
    at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
    at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
    at javafx.scene.control.Control.<clinit>(Control.java:86)
    at sample.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(Native Method)
    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)
    at javafx.graphics/com.sun.glass.ui.gtk.GtkApplication._runLoop(Native Method)
    at javafx.graphics/com.sun.glass.ui.gtk.GtkApplication.lambda$runLoop$11(GtkApplication.java:277)
    ... 1 more
Exception running application sample.Main

I am running a recent version of IntelliJ Idea on Kubuntu. I downloaded the Oracle JDK as well as JavaFX, from the official websites

I put javafx-sdk-11.0.2 in the directory /usr/lib/jvm/ and jdk-11.0.2 is in the same directory.

In IntelliJ Idea, I believe I have correctly chosen the JDK, and I have added /usr/lib/jvm/javafx-sdk-11.0.2/lib as a library.

IntelliJ Idea is using this command to launch the Application (split up for readability):

/usr/lib/jvm/jdk-11.0.2/bin/java
  -Djava.library.path=/usr/lib/jvm/javafx-sdk-11.0.2/lib
  --add-modules javafx.base,javafx.graphics
  --add-reads javafx.base=ALL-UNNAMED
  --add-reads javafx.graphics=ALL-UNNAMED
  -javaagent:/opt/jetbrains/idea-IU-183.4886.37/lib/idea_rt.jar=36031:/opt/jetbrains/idea-IU-183.4886.37/bin
  -Dfile.encoding=UTF-8
  -classpath
    /home/rm/IdeaProjects/JfxPlayground/out/production/JfxPlayground
    :/usr/lib/jvm/javafx-sdk-11.0.2/lib/src.zip
    :/usr/lib/jvm/javafx-sdk-11.0.2/lib/javafx-swt.jar
    :/usr/lib/jvm/javafx-sdk-11.0.2/lib/javafx.web.jar
    :/usr/lib/jvm/javafx-sdk-11.0.2/lib/javafx.base.jar
    :/usr/lib/jvm/javafx-sdk-11.0.2/lib/javafx.fxml.jar
    :/usr/lib/jvm/javafx-sdk-11.0.2/lib/javafx.media.jar
    :/usr/lib/jvm/javafx-sdk-11.0.2/lib/javafx.swing.jar
    :/usr/lib/jvm/javafx-sdk-11.0.2/lib/javafx.controls.jar
    :/usr/lib/jvm/javafx-sdk-11.0.2/lib/javafx.graphics.jar
  -p
    /usr/lib/jvm/javafx-sdk-11.0.2/lib/javafx.base.jar
    :/usr/lib/jvm/javafx-sdk-11.0.2/lib/javafx.graphics.jar
  sample.Main

I have not modified any VM options.

How can I fix this error? Is it a bug in JavaFx?

José Pereda
  • 44,311
  • 7
  • 104
  • 132
Reinis Mazeiks
  • 1,168
  • 1
  • 10
  • 21

4 Answers4

38

You are already giving an explanation of your issue:

I have not modified any VM options.

Since JavaFX 11 is not part of the JDK anymore, you have to use the JavaFX SDK (as you are doing) from here, or alternatively use Maven/Gradle to retrieve the JavaFX modules from Maven Central.

Then you need to add the SDK as a library, so IntelliJ can find the JavaFX classes.

But once you have done that, and given that the JavaFX jars are modules, you still need to do two things:

  • Make the JavaFX modules available to your module-path
  • Define which modules do you add to the project

Based on your IntelliJ output, it is adding by default javafx.graphics and javafx.base:

--add-modules javafx.base,javafx.graphics

-p /usr/lib/jvm/javafx-sdk-11.0.2/lib/javafx.base.jar
:/usr/lib/jvm/javafx-sdk-11.0.2/lib/javafx.graphics.jar

(note that -p is the same as --module-path)

This explains why your project runs in the first case, when you don't have a control added to the scene, just the StackPane, that belongs to the javafx.graphics module, but fails with the posted exception when you add the Label, that belongs to the javafx.controls module.

This has been said a number of times: you need to set the required VM options for your project.

Start by reading the documentation at https://openjfx.io/openjfx-docs/, including the IntelliJ doc, section Non-modular projects for your IDE. And read the part 4. Add VM options.

VM Options

So click on Run -> Edit Configurations, and add:

-p /usr/lib/jvm/javafx-sdk-11.0.2/lib --add-modules javafx.controls

Apply, and run, the issue will be solved.

José Pereda
  • 44,311
  • 7
  • 104
  • 132
  • 6
    is there a way to do the same thing without specifying VM options? – user2914191 Feb 15 '19 at 01:56
  • 9
    @user2914191Execute `javafx:run` from the Maven window. – ItachiUchiha Aug 02 '19 at 14:45
  • Instead of downloading the JavaFX SDK or libraries, another option is using a JDK that includes the JavaFX/OpenJFX libraries. At least two such products: *LibericaFX* from BellSoft, and the *JDK FX* builds of *Azul Platform Core* from Azul Systems. – Basil Bourque Jun 05 '21 at 00:30
0

I would use gradle and the javafx plugin for that.

apply plugin: "org.openjfx.javafxplugin"

javafx {
    version = "11"
    modules = ["javafx.base", "javafx.controls", "javafx.graphics"
}
Beowolve
  • 548
  • 2
  • 13
0

Another option may be useful, especially if you planning to package your application as fat-jar.

Thanks to this answer.

Instead of modifying vm options you can create another Main class which does not extend javafx.application.Application and call your application start method from there. Try the following:

public class App extends Application
{

    @Override public void start(Stage stage)
    {
        // all the stuff necessary
    }

    // Method called "main" here for experimental purposes.
    // But for production use you may decide to call it, "run" for example.
    // Exact name does not matter.
    public static void main(String[] args)
    {
        App.launch();
    }

}

// This class must NOT extend Application. It is a wrapper only.
public class Runner
{
    public static void main(String[] args)
    {
        // Starter method from previous class
        App.main(args);
    }
}

Trying to run App.main() with default configuration (VM options is an empty field) would cause an error, while Runner.main() executes successfully.

For deeper understanding you may compare the java run commands (idea folds them by default) found in Run or Debug windows.

Boris
  • 27
  • 3
-3

check your JAVA_HOME, JAVA_HOME'version must be jdk9+ or jdk11+

远星河
  • 79
  • 1