Pourquoi serait-chargeur de classe.getResourceAsStream() retourne la valeur null?
Ayant le code suivant cassé volontairement afin d'identifier la source d'un NullPointerException dans quelque chose qu'il aurait été très simple mais qui est en fait qui me conduira à la noix:
Properties properties = new Properties();
Thread currentThread = Thread.currentThread();
ClassLoader contextClassLoader = currentThread.getContextClassLoader();
InputStream propertiesStream = contextClassLoader.getResourceAsStream("resource.properties");
if (propertiesStream != null) {
properties.load(propertiesStream);
//TODO close the stream
} else {
//Properties file not found!
}
- Je obtenir le "fichier des Propriétés non trouvé!" erreur, c'est à dire contextClassLoader.getResourceAsStream("des ressources.les propriétés"); retourne null.
C'est un CXF base de client et j'ai vérifié que la "ressource."propriétés de fichier est dans le répertoire courant dans lequel le client du pot de résidence (et court).
J'ai aussi vérifié le chemin d'accès absolu en incluant les éléments suivants de code de diagnostic:
File file = new File("resource.properties");
System.out.println(file.getAbsolutePath());
Le chemin absolu de points à l'endroit où le client est tapissé de.
J'ai aussi essayé de trouver le contexte de la classe de chargement, à l'aide de:
System.out.println(Thread.currentThread().getContextClassLoader());
mais au lieu de cela quelques structure de répertoire comme démontré ici, tout ce que j'obtiens est:
com.simontuffs.onejar.JarClassLoader@1decdec
Pourquoi chargeur de classe.getResourceAsStream() retourne la valeur null?
Ce qui me manque?
Qui CLASSPATH? J'ai imprimé le
classpath
env var et il comprend le répertoire courant ("."). Je suis confus.OriginalL'auteur Withheld | 2014-04-09
Vous devez vous connecter pour publier un commentaire.
J'ai résolu le mystère.
La clé de la solution a été l'incorporation de certains journalisation des diagnostics quand
propertiesStream
est nulle:Donc, quand je lance avec l'original
- Je recevoir le pointeur null condition, d'impression:
.
J'ai alors commencé à me douter de quelque chose lié à la "pot dans un pot" que c'est ce que le com.simontuffs.onejar fait essentiellement (c'est à dire habillage de mon projet du pot à l'intérieur d'un bocal qui contient tous les autres de la bibliothèque des pots), j'ai donc ouvert myproj.one-jar.jar avec 7-Zip et a noté l'complet (absolu) chemin de la "ressource."propriétés de:
.
J'ai donc modifié
getResource("resource.properties")
:qui n'a pas de résoudre le problème, mais imprimé à la suite du pointeur null condition:
.
Puis... l'intervention divine est tombée sur moi et j'ai eu l'intuition (ne pas lire toute la documentation qui pourrait même indice la présente, je vous jure!) que je devrais être en utilisant ce chemin d'accès au lieu:
Et Le Tour Est Joué! Elle fonctionne.
Ouf.
/webapp/WEB-INF/classes/
est implicite et d'automatiquement déterminée), les fichiers JAR exiger le chemin d'accès complet.2 1/2 ans plus tard, je suis venu le long de après la lecture de cette dans au moins 20 autres endroits, aucune n'a résolu mon problème. Mais vous n'avez: ajouter "/webapp" à l'avant de la chaîne résolu mon problème. Je n'ai pas vu que la documentation de n'importe où, donc je n'ai aucune idée de comment vous êtes arrivé à votre point de vue, mais cela m'a fait déménager à nouveau après 1,5 heures d'être coincé. Merci!!!!!
OriginalL'auteur Withheld
Comme EJP souligné, cela signifie que la ressource n'est pas disponible via le chemin de ce chargeur de classe (les différents chargeurs de classes peuvent avoir différents chemins de classe).
Depuis le chargeur de classe est un
JarClassLoader
, il ne sera en mesure de charger les ressources qui sont inclus à l'intérieur de le fichier jar. Elle ne verrez pas les fichiers qui sont dans le même répertoire que le fichier jar.src/main/resources
et lawebapp/WEB-INF/classes
répertoires du projet, inclus dans le fichier JAR. En vain. Ce qui me manque? Est-il possible que le com.simontuffs.onejar.JarClassLoader modifie le chemin d'une certaine façon? Si oui, comment puis-je trouver le de facto classpath?Vérifiez que le
resource.properties
fichier est inclus dans le fichier jar (si vous souhaitez utiliser que des chargeurs de classes à charger). Aussi essayer de le charger comme/resource.properties
(si c'est dans la racine de la jarre).Oui, c'est inclus (dans lieux, au moins pour la phase de débogage) et j'ai essayé les deux
resource.properties
et/resource.properties
. En vain. Quelque chose de méchant qui se passe. Je suis soupçonnant quelque chose de très spécifique à ce "simontuffs"... Comment puis-je imprimer le classpath de l'application client le voit au moment de l'exécution?Il n'existe pas de chemin de classe. Tout dépend de la
ClassLoader
. Il peut déléguer à son parentClassLoader
si elle ne peut pas le trouver par lui-même, mais je pense queJarClassLoader
(commeURLClassLoader
) ne pas déléguer à son parent. Vous pouvez utiliser legetPackages()
méthode pour voir quels paquets le chargeur de classe sait, et assurez-vous que la ressource est dans le pot à la bonne sous-répertoire (par exemple, si le chargeur de classe connaît un package com.foo.bar, le fichier doit être à l'intérieur du bocal com/foo/bar/ressources.les propriétés).J'ai juste utilisé
Package.getPackages()
et il imprime le monde... c'est à dire des centaines de colis, mais pas de chemin ou une allusion à un chemin d'accès. Toujours à essayer de comprendre le bon sous-répertoire. D'autres suggestions sur la façon de comprendre cela est très appréciée.OriginalL'auteur Kayaman