Почему я получаю исключение javafx.fxml.LoadException при загрузке файла FXML? - PullRequest
0 голосов
/ 02 октября 2019

Я использую Java JDK 13 и FontAwesomeFX 11.

У меня есть файл FXML, который содержит некоторые FontAwesomeIconViews, но при загрузке файла в мой контроллер я получаю исключение javafx.fxml.LoadException. Вот как выглядит файл FXML:

<?xml version="1.0" encoding="UTF-8"?>

<?import de.jensd.fx.glyphs.fontawesome.FontAwesomeIconView?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.PasswordField?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.BorderPane?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.text.Font?>

<VBox id="window" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="600.0" prefWidth="800.0" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1">
   <children>
      <BorderPane id="upper" fx:id="upper" prefHeight="50.0" prefWidth="800.0" stylesheets="@style.css">
         <left>
            <Label text="TEXT" BorderPane.alignment="CENTER">
               <font>
                  <Font size="20.0" />
               </font>
            </Label>
         </left>
         <right>
            <HBox prefHeight="100.0" prefWidth="200.0" BorderPane.alignment="CENTER">
               <children>
LINE 27           <FontAwesomeIconView glyphName="WINDOW_MINIMIZE" size="20" />
                  <FontAwesomeIconView glyphName="CLOSE" size="30" />
               </children></HBox>
         </right>
      </BorderPane>
      <AnchorPane id="body" prefHeight="554.0" prefWidth="800.0">
         <children>
            <TextField layoutX="326.0" layoutY="233.0" promptText="Usuario" />


<PasswordField layoutX="326.0" layoutY="276.0" promptText="Contraseña" />
        <Button layoutX="353.0" layoutY="334.0" mnemonicParsing="false" prefHeight="25.0" prefWidth="94.0" text="Acceder" />
        <Label layoutX="326.0" layoutY="372.0" text="¿Ha olvidado la contraseña?" />
        <FontAwesomeIconView glyphName="USER_CIRCLE" layoutX="350.0" layoutY="185.0" size="100" />
     </children>
  </AnchorPane>
</children>
</VBox>
</children>
</VBox>

Я получаю сообщение об ошибке первого элемента FontAwesomeIconView (WINDOW_MINIMIZE).

У меня есть подозрения, что это может быть потому, что FontAwesomeFX 11 ожидает FontAwesomeIconViewsбыть отформатированным по-другому, но я совсем не уверен.

Error al cargar el archivo vista Login.fxml: javafx.fxml.LoadException: 
.../bin/view/login.fxml:27

Exception in thread "JavaFX Application Thread" java.lang.NullPointerException: Root cannot be null
    at javafx.graphics/javafx.scene.Scene.<init>(Scene.java:345)
    at javafx.graphics/javafx.scene.Scene.<init>(Scene.java:236)
    at controller.SplashController$SplashScreen$2.run(SplashController.java:78)
    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)
    at javafx.graphics/com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
    at javafx.graphics/com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:174)
    at java.base/java.lang.Thread.run(Thread.java:830)

1 Ответ

5 голосов
/ 02 октября 2019

Всякий раз, когда вы получаете javafx.fxml.LoadException, вы должны прочитать всю трассировку стека до самого конца. Как правило, в конце будет отображаться реальная причина для исключения.

Допустим, у вас есть этот build.gradle файл, и ваш проект является немодулярным:

plugins {
  id 'application'
  id 'org.openjfx.javafxplugin' version '0.0.8'
}

repositories {
    jcenter()
}

dependencies {
    implementation "de.jensd:fontawesomefx-commons:11.0"
    implementation "de.jensd:fontawesomefx-fontawesome:4.7.0-11"
}

mainClassName = 'org.openjfx.MainApp'

javafx {
    modules = [ 'javafx.controls', 'javafx.fxml' ]
}

и файл FXML с FontAwesomeIconView:

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.layout.VBox?>
<?import de.jensd.fx.glyphs.fontawesome.FontAwesomeIconView?>

<VBox maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/11" xmlns:fx="http://javafx.com/fxml/1" fx:controller="org.openjfx.FXMLController">
      <FontAwesomeIconView glyphName="WINDOW_MINIMIZE" size="20" />
</VBox>

Затем вы запускаете проект:

./gradlew clean run

и получаете:

java.lang.reflect.InvocationTargetException
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
 ...
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: javafx.fxml.LoadException: 
/.../build/resources/main/org/openjfx/scene.fxml:7
        at javafx.fxml/javafx.fxml.FXMLLoader.constructLoadException(FXMLLoader.java:2625)
        at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2603)

Если вы перестанете читать там, вы подумаете, что что-то не так с строкой scene.fxml:7, которая является FontAwesomeIconView.

Но если вы продолжите читать трассировку стека:

java.lang.reflect.InvocationTargetException
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
 ...
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: javafx.fxml.LoadException: 
/.../build/resources/main/org/openjfx/scene.fxml:7
        at javafx.fxml/javafx.fxml.FXMLLoader.constructLoadException(FXMLLoader.java:2625)
        at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2603)

...
Caused by: java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
        at javafx.fxml/com.sun.javafx.fxml.BeanAdapter.put(BeanAdapter.java:262)
...
Caused by: java.lang.reflect.InaccessibleObjectException: \
    Unable to make javafx.css.ParsedValue javafx.css.CssParser.parseExpr(java.lang.String,java.lang.String) accessible: \
    module javafx.graphics does not "opens javafx.css" to unnamed module @32ab3e54
    ...
     at de.jensd.fx.glyphs.GlyphIcon.convert(GlyphIcon.java:248)
... 

последний Caused by точно указывает причину проблемы:

модуль javafx.graphics не "открывает javafx.css" для неназванного модуля @ 32ab3e54

Этоиз-за использования отражения в GlyphIcon для доступа к частному API.

Итак, теперь, когда вы знаете причину, все, что вам нужно сделать, это предоставить решение: в этом случае мы добавим запрошенный --add-opens к аргументам jvm в файле build.gradle:

run {
    jvmArgs = ["--add-opens", "javafx.graphics/javafx.css=ALL-UNNAMED"]
}

При повторном запуске он будет работать.

Примечание 1

Еслиу вас есть модульный проект, с дескриптором информации модуля, например:

module hellofx {
    requires javafx.controls;
    requires javafx.fxml;
    requires de.jensd.fx.fontawesomefx.fontawesome;

    opens org.openjfx to javafx.fxml;
    exports org.openjfx;
}

, затем вы должны добавить вместо:

run {
    jvmArgs = ["--add-opens", "javafx.graphics/javafx.css=de.jensd.fx.fontawesomefx.commons"]
}

Note 2

Если вы не используете Gradle, вы все равно можете сделать то же самое.

Для начала проверьте руководство JavaFX 13 с Eclipse: https://openjfx.io/openjfx-docs/#IDE-Eclipse,, а затем выберите ваш случай.

Если ваш случай немодульный из IDE, при установке аргументов VMнапример:

--module-path /path/to/javafx-sdk-13/lib --add-modules javafx.controls,javafx.fxml

все, что вам нужно сделать сейчас, это включить дополнительный аргумент, например:

--module-path /path/to/javafx-sdk-13/lib --add-modules javafx.controls,javafx.fxml \
--add-opens javafx.graphics/javafx.css=ALL-UNNAMED

Для других случаев логика та же.

...