web-dev-qa-db-fra.com

JavaFX et maven: NullPointerException: l'emplacement est requis

J'ai essayé de configurer Maven avec JavaFX. Même si je n'avais pas d'expérience avec Maven et JavaFX, je ne m'attendais pas à ce que ce soit autant un défi. Mes connaissances Java sont assez solides (y compris Swing), et je ne m'attendais pas à avoir autant de difficulté à les configurer.

J'ai commencé avec un projet JavaFX fourni par IntelliJ 13.0 Community Edition. Le code de ma classe principale est relativement petit:

package sample;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;

public class Main extends Application
{
    @Override
    public void start(Stage primaryStage) throws Exception
    {
        //getClass().getResource("../../resources/sample.fxml");
        Parent root = FXMLLoader.load(getClass().getResource("../sample.fxml"));
        primaryStage.setTitle("Hello World");
        primaryStage.setScene(new Scene(root, 300, 275));
        primaryStage.show();
    }


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

et mon pom.xml n'est pas trop grand non plus:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.Apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.Apache.org/POM/4.0.0 http://maven.Apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>sample</groupId>
    <artifactId>JavaFXDemo</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>

    <organization>
        <name>RubberDucky</name>
    </organization>

    <build>
        <pluginManagement>
            <plugins>
                <plugin>
                    <groupId>com.zenjava</groupId>
                    <artifactId>javafx-maven-plugin</artifactId>
                    <version>2.0</version>
                </plugin>
            </plugins>
        </pluginManagement>
        <plugins>
            <plugin>
                <groupId>com.zenjava</groupId>
                <artifactId>javafx-maven-plugin</artifactId>
                <version>2.0</version>
                <configuration>
                    <mainClass>sample.Main</mainClass>
                </configuration>
            </plugin>
        </plugins>
    </build>

    <dependencies>
        <dependency>
            <groupId>com.Oracle</groupId>
            <artifactId>javafx</artifactId>
            <version>2.2</version>
            <systemPath>${Java.home}/lib/jfxrt.jar</systemPath>
            <scope>system</scope>
        </dependency>
    </dependencies>
</project>

J'utilise JavaFX Maven Plugin pour construire l'application. Après avoir exécuté mvn clean jfx:jar tout semble aller bien, toutes les versions réussissent. Mais lorsque j'essaie d'exécuter l'application, j'obtiens l'erreur suivante:

Exception in Application start method
Java.lang.reflect.InvocationTargetException
        at Sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at Sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
        at Sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
        at Java.lang.reflect.Method.invoke(Unknown Source)
        at com.javafx.main.Main.launchApp(Main.Java:698)
        at com.javafx.main.Main.main(Main.Java:871)
Caused by: Java.lang.RuntimeException: Exception in Application start method
        at com.Sun.javafx.application.LauncherImpl.launchApplication1(Unknown So
urce)
        at com.Sun.javafx.application.LauncherImpl.access$000(Unknown Source)
        at com.Sun.javafx.application.LauncherImpl$1.run(Unknown Source)
        at Java.lang.Thread.run(Unknown Source)
Caused by: Java.lang.NullPointerException: Location is required.
        at javafx.fxml.FXMLLoader.load(Unknown Source)
        at javafx.fxml.FXMLLoader.load(Unknown Source)
        at javafx.fxml.FXMLLoader.load(Unknown Source)
        at javafx.fxml.FXMLLoader.load(Unknown Source)
        at javafx.fxml.FXMLLoader.load(Unknown Source)
        at sample.Main.start(Main.Java:15)
        at com.Sun.javafx.application.LauncherImpl$5.run(Unknown Source)
        at com.Sun.javafx.application.PlatformImpl$5.run(Unknown Source)
        at com.Sun.javafx.application.PlatformImpl$4$1.run(Unknown Source)
        at com.Sun.javafx.application.PlatformImpl$4$1.run(Unknown Source)
        at Java.security.AccessController.doPrivileged(Native Method)
        at com.Sun.javafx.application.PlatformImpl$4.run(Unknown Source)
        at com.Sun.glass.ui.InvokeLaterDispatcher$Future.run(Unknown Source)
        at com.Sun.glass.ui.win.WinApplication._runLoop(Native Method)
        at com.Sun.glass.ui.win.WinApplication.access$100(Unknown Source)
        at com.Sun.glass.ui.win.WinApplication$3$1.run(Unknown Source)
        ... 1 more

Après un débogage approximatif, le problème semble être dans le chemin à partir duquel je charge mes fichiers. Après avoir codé en dur le sample.fxml à un emplacement sur mon disque dur, l'application s'exécute sans problème. Il en va de même pour la configuration actuelle (vue ci-dessus) lors de l'exécution de l'application à partir d'IntelliJ.

J'ai l'impression d'avoir épuisé toutes les ressources (y compris StackOverflow, certaines erreurs très similaires) mais je ne peux pas comprendre exactement ce qui ne va pas.

32
OxySocks

Assurez-vous que votre sample.fxml Se trouve dans le répertoire src/main/resources/ (Ou un sous-répertoire). Ensuite, vous pouvez accéder au fichier comme ceci:

Parent root = FXMLLoader.load(getClass().getClassLoader().getResource("sample.fxml"));

Explication: Pendant la phase de compilation, toutes les ressources et classes sont copiées dans target/classes/. Votre fichier fxml réside donc dans ce répertoire et votre classe dans un sous-répertoire concernant son nom de package. Si vous appelez getClass().getResource("sample.fxml"); le fichier sera recherché par rapport au fichier de classe qui sera ce répertoire: target/classes/sample/.

L'appel de .getResource() sur le chargeur de classe définit le chemin de recherche relatif sur target/classes/ Et donc votre fichier est trouvé.

P.S. Vous pouvez également écrire:

Parent root = FXMLLoader.load(getClass().getResource("/sample.fxml"));
83
Absurd-Mind

Comme @ Absurd-Mind l'a déjà expliqué, maven ne copiera aucun fichier de ressources (comme fxml) qui réside dans le répertoire src.

Si vous souhaitez conserver les fichiers fxml en plus des fichiers source Java, vous pouvez utiliser le plugin de ressources maven pour les copier:

<build>
    ...
    <resources>
        <resource>
            <filtering>false</filtering>
            <directory>src/main/Java</directory>
            <includes>
                <include>**/*.fxml</include>
            </includes>             
        </resource>
    </resources>
    ...
</build>
10
mrak

J'ai eu le même problème avec Intelij et Gradle.

Étapes à suivre:

1. déplacer le fichier

sample.fxml

au chemin

\ src\main\resources\fxml

  1. Définissez le chemin sur ce fichier:

Racine parent = FXMLLoader.load (getClass (). GetResource ("/ fxml/sample.fxml"));

5
Kamil Nekanowicz

Pour ceux qui utilisent gradle comme système de construction, ajoutez ceci à votre build.gradle fichier:

sourceSets.main.resources {
    srcDirs = ["src/main/Java"]; //assume that your Java classes are inside this path
    exclude "**/*.Java"
}

Ensuite, nettoyez et reconstruisez votre projet.

Alors qu'est-ce que ça va faire? Si tu as un view.fxml à l'intérieur de votre com.example.myfxapp package, après avoir construit votre projet, il sera exporté vers <build dir>/resources/com/example/myfxapp/view.fxml

2
Saeed Masoumi

Pour moi, j'avais pris soin de suivre les choses -

  1. Assurez-vous que le fichier fxml est placé là où réside votre classe principale. Et puis chargez-le en utilisant ceci - (Dans mon cas, TechJFX.fxml est le fichier)

    FXMLLoader loader = new FXMLLoader(getClass().getResource("TechJFX.fxml"));
    
  2. Ajoutez opencv - *. Jar à votre dossier de projet (dans mon cas opencv-300.jar)

  3. Ajoutez le pot au chemin de génération à l'aide de

Faites un clic droit sur le dossier du projet -> Chemin de génération -> Configurer le chemin de génération -> Onglet Bibliothèques -> Ajouter des fichiers JAR externes et localisez le fichier

Aussi, sous Ordre et exportation -> Cochez opencv-300.jar et bibliothèque système JRE (si ce n'est pas déjà fait)

  1. Copiez opencv_Java * .dll (dans mon cas opencv_Java300.dll) au même emplacement que celui où se trouve votre fichier JAR dans le dossier du projet.

  2. Ajoutez la méthode suivante à votre classe principale

     static{ 
            System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
       }
    
  3. Terminé.

J'espère que cela aidera quelqu'un confronté à un problème similaire.

0
Techidiot