65 votes

this.getClass().getClassLoader().getResource("...") et NullPointerException

J'ai créé un projet maven minimal avec un seul module enfant dans eclipse helios.

Dans le dossier src/test/resources, j'ai placé un seul fichier "install.xml". Dans le dossier src/test/java j'ai créé un seul paquet avec une seule classe qui fait :

  @Test
  public void doit() throws Exception {
    URL url = this.getClass().getClassLoader().getResource("install.xml");
    System.out.println(url.getPath());

  }

mais lorsque j'exécute le code en tant que test unitaire junit 4, j'obtiens simplement une NullPointerException. Cela a pourtant bien fonctionné des millions de fois auparavant. Avez-vous une idée ?

J'ai suivi ce guide :

http://www.fuyun.org/2009/11/how-to-read-input-files-in-maven-junit/

mais je reçois toujours la même erreur.

104voto

AmishDave Points 525

Lorsque vous utilisez

this.getClass().getResource("myFile.ext")

getResource va essayer de trouver la ressource relative au paquet. Si vous utilisez :

this.getClass().getResource("/myFile.ext")

getResource le traitera comme un chemin absolu et appellera simplement le chargeur de classe comme vous l'auriez fait si vous aviez fait.

this.getClass().getClassLoader().getResource("myFile.ext")

La raison pour laquelle vous ne pouvez pas utiliser le premier / dans le ClassLoader c'est parce que tous les ClassLoader Les chemins sont absolus et donc / n'est pas un premier caractère valide dans le chemin.

0 votes

Il s'est avéré que le pom parent utilisé par mon équipe ne comprend que *.xml et *.properties. Maintenant... je ne sais pas pourquoi cela a fonctionné sur ma station de travail Windows. J'ai même regardé dans mon repo maven local pour vérifier qu'il avait le même pom que celui de la machine linux.

2 votes

Bonjour @AmishDave, votre question de suivi (si vous avez toujours besoin d'une réponse) devrait être postée comme une nouvelle question. N'hésitez pas à créer un lien vers cette question et/ou cette réponse, mais le fait d'avoir une question de suivi dans une réponse ne correspond pas à la façon dont Stack Overflow fonctionne habituellement. Merci ! :-)

39voto

Namalak Points 2121

Tul,

  • Lorsque vous utilisez .getClass().getResource(fileName) il considère le l'emplacement du fileName est le même que celui de la classe appelante. classe.
  • Lorsque vous utilisez .getClass().getClassLoader().getResource(fileName) il considère que l'emplacement du nom du fichier est la racine - en d'autres termes bin carpeta.

Source :

package Sound;
public class ResourceTest {
    public static void main(String[] args) {
        String fileName = "Kalimba.mp3";
        System.out.println(fileName);
        System.out.println(new ResourceTest().getClass().getResource(fileName));
        System.out.println(new ResourceTest().getClass().getClassLoader().getResource(fileName));
    }
}

Sortie :

Kalimba.mp3
file:/C:/Users/User/Workspaces/MyEclipse%208.5/JMplayer/bin/Sound/Kalimba.mp3
file:/C:/Users/User/Workspaces/MyEclipse%208.5/JMplayer/bin/Kalimba.mp3

0 votes

Que dois-je faire pour avoir les ressources Maven du dossier resources dans le bin ? Je constate que même lorsque je lance l'installation de Maven, elles n'y apparaissent pas. Mais j'ai probablement mal compris quelque chose :)

21voto

mhaller Points 10002

Il devrait être getResource("/install.xml");

Les noms des ressources sont relatifs à l'endroit où la classe getClass() réside, par exemple si votre test est org/example/foo/MyTest.class puis getResource("install.xml") regardera dans org/example/foo/install.xml .

Si votre install.xml est en src/test/resources il se trouve à la racine du chemin de classe, d'où la nécessité de faire précéder le nom de la ressource de la mention / .

De plus, si cela ne fonctionne que parfois, cela peut être dû au fait qu'Eclipse a nettoyé le répertoire de sortie (par ex. target/test-classes ) et la ressource est simplement absente du classpath de l'exécution. Vérifiez cela en utilisant la vue Navigateur d'Eclipse au lieu de l'explorateur de paquets. Si les fichiers sont manquants, exécutez la commande mvn package objectif.

1 votes

J'ai également essayé : this.getClass().getClassLoader().getResource("/install.xml") ; cela n'aide pas (Tous mes autres projets qui lisent les ressources n'utilisent pas le préfixe "/" et ils fonctionnent bien). J'ai également essayé d'exécuter mvn clean install (à la fois en ligne de commande et à partir d'eclipse) sur le parent et l'enfant mais toujours le même problème. Lorsque je vérifie le dossier enfant : target/test-classes dans la vue du navigateur, il est vide - je suppose que c'est mauvais.

0 votes

Oui, c'est mauvais. Affichez la partie de votre pom où vous avez spécifié (le cas échéant) les balises <resources>. Peut-être faites-vous des <include> ou <exclude> là-dedans ? mvn install devrait certainement copier vos fichiers de ressources dans le dossier classes resp. test-classes. Utilisez-vous M2Eclipse ?

0 votes

Je n'ai pas touché aux déclarations include/exclude. J'ai trouvé ceci : issues.sonatype.org/browse/MNGECLIPSE-823 qui pourrait traiter de cette question. J'ai créé un nouveau projet et cela fonctionne à nouveau.

6voto

dmc7337 Points 304

Quand eclipse exécute le cas de test, il cherchera le fichier dans target/classes et non src/test/resources. Lorsque la ressource est sauvegardée, eclipse devrait la copier de src/test/resources vers target/classes si elle a changé, mais si pour une raison quelconque, cela ne s'est pas produit, vous obtiendrez cette erreur. Vérifiez que le fichier existe dans target/classes pour voir si c'est le problème.

5voto

Hilbrand Bouwkamp Points 11496

J'ai eu le même problème avec les conditions suivantes :

  • Les fichiers de ressources se trouvent dans le même paquetage que les fichiers source java, dans le dossier source java ( src/test/java ).
  • J'ai construit le projet avec maven sur la ligne de commande et la construction a échoué sur les tests avec l'erreur suivante NullPointerException .
  • La compilation en ligne de commande n'a pas copié les fichiers de ressources dans le dossier de l'utilisateur. test-classes ce qui explique l'échec de la construction.
  • Lorsque je me suis rendu dans eclipse après la construction en ligne de commande et que j'ai réexécuté les tests dans eclipse, j'ai également obtenu le message suivant NullPointerException en éclipse.
  • Lorsque j'ai nettoyé le projet (supprimé le contenu du dossier cible) et reconstruit le projet dans Eclipse, le test s'est exécuté correctement. Cela explique pourquoi il s'exécute lorsque vous commencez avec un projet propre.

J'ai résolu ce problème en plaçant les fichiers de ressources dans le dossier des ressources de test : src/test/resources en utilisant la même structure de paquetage que la classe source.

BTW j'ai utilisé getClass().getResource(...)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X