web-dev-qa-db-fra.com

JavaFX 11: IllegalAccessError lors de la création d'une étiquette

Cette question concerne probablement le même problème que celui-ci , mais il semble que le demandeur n'a pas ajouté suffisamment d'informations pour recevoir une réponse utile.

J'essaie d'exécuter une application JavaFx avec JDK et JavaFx SDK version 11.0.2.

Ce code fonctionne exactement comme prévu, produisant une fenêtre vide:

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);
    }
}

Cependant, si j'essaie d'ajouter une étiquette au StackPane, une exception est levée.

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);
    }
}

La trace de pile qu'elle produit ressemble à ceci (la ligne 13 dans Main est l'endroit où le Label est créé):

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

J'utilise une version récente d'IntelliJ Idea sur Kubuntu. J'ai téléchargé Oracle JDK ainsi que JavaFX sur les sites officiels

Je mets javafx-sdk-11.0.2 dans le répertoire /usr/lib/jvm/ et jdk-11.0.2 est dans le même répertoire.

Dans IntelliJ Idea, je pense avoir correctement choisi le JDK et j'ai ajouté /usr/lib/jvm/javafx-sdk-11.0.2/lib en tant que bibliothèque.

IntelliJ Idea utilise cette commande pour lancer l'application (divisée pour plus de lisibilité):

/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

Je n'ai modifié aucune option VM.

Comment puis-je corriger cette erreur? Est-ce un bug dans JavaFx?

18
Reinis Mazeiks

Vous donnez déjà une explication de votre problème:

Je n'ai modifié aucune option VM.

Comme JavaFX 11 ne fait plus partie du JDK, vous devez utiliser le SDK JavaFX (comme vous le faites) à partir de ici , ou bien utiliser Maven/Gradle pour récupérer les modules JavaFX à partir de Maven Central.

Ensuite, vous devez ajouter le SDK en tant que bibliothèque, afin qu'IntelliJ puisse trouver les classes JavaFX.

Mais une fois que vous avez fait cela, et étant donné que les jars JavaFX sont des modules, vous devez toujours faire deux choses:

  • Rendre les modules JavaFX disponibles sur votre chemin de module
  • Définissez les modules que vous ajoutez au projet

En fonction de votre sortie IntelliJ, il ajoute par défaut javafx.graphics et 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

(Notez que -p est le même que --module-path)

Cela explique pourquoi votre projet s'exécute dans le premier cas, lorsque vous n'avez pas de contrôle ajouté à la scène, juste le StackPane, qui appartient au javafx.graphicsmodule , mais échoue avec l'exception publiée lorsque vous ajoutez le Label, qui appartient au javafx.controlsmodule .

Cela a été dit plusieurs fois: vous devez définir les options VM VM pour votre projet).

Commencez par lire la documentation sur https://openjfx.io/openjfx-docs/ , y compris le document IntelliJ , section Projets non modulaires pour votre IDE. Et lisez la partie 4. Ajoutez VM options.

VM Options

Cliquez donc sur Exécuter -> Modifier les configurations et ajoutez:

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

Appliquer et exécuter, le problème sera résolu.

19
José Pereda