Comportement étrange de la classe.getResource () et ClassLoader.getResource () dans jar exécutable
Je comprends de Quelle est la différence entre la classe.getResource () et ClassLoader.getResource()? et à partir de son propre code, que
getClass().getResource("/path/image.png")
Est identique à
getClass().getClassLoader().getResource("path/image.png")
L'affichage ne peut pas lire une image dans le fichier jar montre un problème où l'utilisation de
getClass().getClassLoader().getResource("path/image.png")
Dans un fichier JAR exécutable renvoie null, tandis que
getClass().getResource("/path/image.png")
Renvoie L'URL correcte.
Since Class.getResource()
délégués à ClassLoader.getResource()
après avoir supprimé la barre oblique principale, je m'attendrais à ce que ces appels soient identiques, mais évidemment ils ne sont pas dans ce cas. Même lorsqu'un chargeur de classe spécial est attaché à la classe particulière, il doit toujours être le même pour chaque appel, ce qui entraîne le même comportement.
Donc, la question Est: y a-t-il des circonstances évidentes dans lesquelles les éléments suivants le code renvoie null pour le premier appel mais l'URL appropriée pour le second appel?
package com.example;
import java.net.URL;
public class ResourceTest {
public void run() {
URL iconUrl1 = getClass().getClassLoader().getResource("path/image.png");
System.out.println("ClassLoader.getResource("path/image.png"): " + iconUrl1);
URL iconUrl2 = getClass().getResource("/path/image.png");
System.out.println("Class.getResource("/path/image.png"): " + iconUrl2);
}
public static void main(String[] args) {
ResourceTest app = new ResourceTest();
app.run();
}
}
1 réponses
Je pensais que cette question était déjà posée et répondue!
getClass().getResource()
recherches relatives à la .fichier de classe tout engetClass().getClassLoader().getResource()
Recherche par rapport au chemin de classe racine.
S'il y a un SSCCE ici, Je ne comprends pas pourquoi ce n'est pas le cas
1) Affiche l'organisation du répertoire dans le .jar et...
2) Prendre le paquet dans examen
Q: Ce qui (le cas échéant) n'a pas déjà été répondu par Quelle est la différence entre la classe.getResource () et ClassLoader.getResource()? (et les liens qu'il cite)?
=========================================================================
Je ne suis toujours pas sûr de ce qui n'est pas clair, mais cet exemple pourrait aider:
/*
SAMPLE OUTPUT:
ClassLoader.getResource(/subdir/readme.txt): NULL
Class.getResource(/subdir/readme.txt): SUCCESS
ClassLoader.getResource(subdir/readme.txt): SUCCESS
Class.getResource(subdir/readme.txt): NULL
*/
package com.so.resourcetest;
import java.net.URL;
public class ResourceTest {
public static void main(String[] args) {
ResourceTest app = new ResourceTest ();
}
public ResourceTest () {
doClassLoaderGetResource ("/subdir/readme.txt");
doClassGetResource ("/subdir/readme.txt");
doClassLoaderGetResource ("subdir/readme.txt");
doClassGetResource ("subdir/readme.txt");
}
private void doClassLoaderGetResource (String sPath) {
URL url = getClass().getClassLoader().getResource(sPath);
if (url == null)
System.out.println("ClassLoader.getResource(" + sPath + "): NULL");
else
System.out.println("ClassLoader.getResource(" + sPath + "): SUCCESS");
}
private void doClassGetResource (String sPath) {
URL url = getClass().getResource(sPath);
if (url == null)
System.out.println("Class.getResource(" + sPath + "): NULL");
else
System.out.println("Class.getResource(" + sPath + "): SUCCESS");
}
}
Voici l'arborescence correspondante. Il se trouve que c'est un projet Eclipse, mais les répertoires sont les mêmes peu importe si C'est Eclipse, Netbeans ... ou une .fichier jar:
C:.
├───.settings
├───bin
│ ├───com
│ │ └───so
│ │ └───resourcetest
│ └───subdir
└───src
├───com
│ └───so
│ └───resourcetest
└───subdir
Le fichier en cours d'ouverture est " subdir / readme.txt "
Additif 11/9/12:
Salut -
J'ai copié votre code textuellement à partir de github, recompilé et réexécuté:
ClassLoader.getResource(/subdir/readme.txt): NULL
Class.getResource(/subdir/readme.txt): SUCCESS
ClassLoader.getResource(subdir/readme.txt): SUCCESS
Class.getResource(subdir/readme.txt): NULL
Si pas la sortie que vous obtenez ... Je suis perplexe.
Pour ce que ça vaut, Je cours:
-
Eclipse Indigo (ça ne devrait pas avoir d'importance)
Courir à l'intérieur de L'IDE (il peu importe si c'est le système de fichiers ou .pot, à l'intérieur ou à l'extérieur d'un IDE)
-
Mon JRE est 1.6 (Si quoi que ce soit, c'est probablement le biggie)
Désolé, nous n'avons pas été en mesure de résoudre ce que je pensé était un problème simple: (
Additif 11/21/12 (Andreas):
Comme il n'y a pas eu d'activité récente sur cette question, je voudrais résumer ce que nous avons trouvé:
- de notre compréhension commune, la réponse à ce qui précède la question Est: "Non, il n'est pas possible que
Class.getResource("/path/image.png")
renvoie une URL valide, tandis queClassLoader.getResource("path/image.png")
renvoie null" :- Nous sommes complètement clairs sur la différence entre ClassLoader.getResource () et Class.getResource ()
- nos exemples de sorties correspondent, à la fois pour "SUCCESS "et pour"null"
- les sorties de l'échantillon correspondent à ce que nous attendons
- Conclusion: soit nous avons supervisé quelque chose, soit quelque chose de différent a fait fonctionner la "solution" décrite dans la question liée. Je pense que nous ne peut pas actuellement prouver l'un ou l'autre.