IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Java Discussion :

getResourceAsStream dans une API


Sujet :

Java

  1. #1
    Membre régulier
    Inscrit en
    Avril 2008
    Messages
    184
    Détails du profil
    Informations personnelles :
    Âge : 48

    Informations forums :
    Inscription : Avril 2008
    Messages : 184
    Points : 90
    Points
    90
    Par défaut getResourceAsStream dans une API
    Bonjour,

    Je sais que le sujet est recurant mais je ne trouve pas la solution.

    J'ai une API contenant dans images. Dans cette meme API j'ai une methode static permettant d'aller chercher ces images et qui contient :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    InputStream is;
                is = ClassLoader.getSystemClassLoader().getResourceAsStream("com/fdilogbox/tools/resources/flag/" + codeFlag.toLowerCase() + ".png");
    Si je lance les TU de cette API ca marche bien.

    Ca se complique lorsque j'utilise cette API dans une application, la, il ne trouve plus les images :-(

    Une idée? J'ai essayé pas mal de chose dont :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    Flag.class.getClassLoader().getResourceAsStream(...)
    Flag.class.getResourceAsStream(...)
    Mais ce ne marche pas.

  2. #2
    Membre confirmé
    Profil pro
    Inscrit en
    Décembre 2003
    Messages
    476
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2003
    Messages : 476
    Points : 595
    Points
    595
    Par défaut
    Salut,

    Sans connaitre la structure exacte de ton application et la localisation du fameux fichier introuvable à l'exécution, pas facile de te donner une réponse claire

    Tu dis que ca ne marche pas dans ton appli.
    C'est quoi ton appli : un jar, un war, un ear, etc ?

    Ensuite, comment est packagé ton image dans ton appli ?
    Il est dans un jar, un war, etc ?
    Ils flottent tous en bas

  3. #3
    Membre régulier
    Inscrit en
    Avril 2008
    Messages
    184
    Détails du profil
    Informations personnelles :
    Âge : 48

    Informations forums :
    Inscription : Avril 2008
    Messages : 184
    Points : 90
    Points
    90
    Par défaut
    Exacte

    Alors, mes images sont dans un jar. Le meme jar ou il y a ma methode static pour y acceder.

    Mon application est elle aussi dans un jar. Mais le jar de mes images n'est pas englober dans le jar de mon application mais mis a coté (classpath dans le manifest).

    J'espere qu'il y a toutes les info.

  4. #4
    Membre confirmé
    Profil pro
    Inscrit en
    Décembre 2003
    Messages
    476
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2003
    Messages : 476
    Points : 595
    Points
    595
    Par défaut
    Salut,

    Merci pour les précisions
    Ca m'a l'air plutôt cohérent : tu utilises un chemin relatif à partir du System. Par contre, je suis pas sûr du résultat avec le classLoader que tu utilises. Perso, je ne l'utilise jamais pour charger manuellement une ressource.

    Essaye de remplacer ClassLoader.getSystemClassLoader().getResourceAsStreap() par
    System.class.getClassLoader().getResourceAsStream("/com/fdilogbox/tools/resources/flag/" + codeFlag.toLowerCase() + ".png");
    Note bien le / en début de chaine.
    Ils flottent tous en bas

  5. #5
    Membre régulier
    Inscrit en
    Avril 2008
    Messages
    184
    Détails du profil
    Informations personnelles :
    Âge : 48

    Informations forums :
    Inscription : Avril 2008
    Messages : 184
    Points : 90
    Points
    90
    Par défaut
    Merci.

    Par contre j'ai une erreur : NullPointerException. sur le System.class.getClassLoader()

    Une idée?

  6. #6
    Membre éclairé Avatar de Ceddoc
    Homme Profil pro
    Développeur Java
    Inscrit en
    Janvier 2009
    Messages
    493
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Janvier 2009
    Messages : 493
    Points : 698
    Points
    698
    Par défaut
    J'ai déjà été confronté plus ou moins au même genre de problème et parfois en bidouillant un peu, par exemple en copiant la ressource dans un fichier temporaire avant de l'exploiter, ça résous certains problème. (Mais il est évident que ça ne t'aideras pas à enlever ta NPE sur le System.class.getClassLoader)

  7. #7
    Membre régulier
    Inscrit en
    Avril 2008
    Messages
    184
    Détails du profil
    Informations personnelles :
    Âge : 48

    Informations forums :
    Inscription : Avril 2008
    Messages : 184
    Points : 90
    Points
    90
    Par défaut
    Apres si vous voyez d'autre moyen pour aller chercher une icone dans un jar, je suis preuneur

  8. #8
    Membre confirmé
    Profil pro
    Inscrit en
    Décembre 2003
    Messages
    476
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2003
    Messages : 476
    Points : 595
    Points
    595
    Par défaut
    System.class.getClassLoader() te renvoie un nullpointerException ????
    Je pense que ca doit plutot te renvoyer null (le nullpointer c'est quand t'appelles getResource() ).

    Arf, c'est surement parce que ta classe System a été chargée par le classloader bootstrap. Dans les webapps sur lequel je travaille, ce n'est pas le cas je pense.

    Essaye avec le classLoader du thread en cours, ca ca marche tout le temps A moins que tu n'aies pas de thread. Mais si c'est le cas, félicitations, t'as créé une nouvelle implémentation de java
    Non sans blague, j'espère que ca va marcher cette fois

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    Thread.currentThread().getContextClassLoader().getResourceAsStream("com/fdilogbox/tools/resources/flag/" + codeFlag.toLowerCase() + ".png");
    Note bien l'absence de / cette fois. C'est comme si il y en avait déja un par défaut.

    Et si ca marche pas, ma dernière proposition serait d'utiliser le classloader d'une classe se trouvant dans le jar qui contient ta ressource à charger (ca pourrait être la classe avec la méthode statique qui se charge justement de récupérer la ressource).
    Je pense qu'en passant par le classloader qui a chargé une classe se trouvant dans le même jar, il devra être content
    L'inconvénient de cette solution, c'est qu'on corrèle notre ressource à une classe. Mais bon tu veux une solution à tout prix, je m'exécute
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    TaClasseQuiFaitLeGetResource.class.getResourceAsStream("/com/fdilogbox/tools/resources/flag/" + codeFlag.toLowerCase() + ".png");
    Note bien la présence de / cette fois sinon chemin relatif.
    Ils flottent tous en bas

  9. #9
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    si les images sont dans le jar, même jar qui contient la classe dont le boulot est de les charger, alors le plus propre c'est de passer par le classloader de cette dite classe.

    Tu n'a aucune garantie que le classloader sytème ou que le classloader courant n'aie accès à cette classe, il peux y avoir des tonnes de raisons pour ça (classloader custom pour un plugin, architecture J2EE, etc).

  10. #10
    Membre confirmé
    Profil pro
    Inscrit en
    Décembre 2003
    Messages
    476
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2003
    Messages : 476
    Points : 595
    Points
    595
    Par défaut
    Salut tchize_,

    Je comprends bien.
    Maintenant, comme évoqué plus haut, je trouve que cette solution qui marche à coup sûr présente un inconvénient : on corrèle notre ressource à une classe. Aussi, je la trouve pas si propre que ca...
    Imaginons que notre jar ne contient que des fichiers xml et pas de classe java, comment faire alors ? Exemple peut-être abbérant mais c'est arrivé sur un projet que j'ai récupéré récemment et comme solution de contournement j'ai dû créé une classe java dont le seul but est de charger la ressource.
    Je me demandais justement cette après midi si il n'y avait pas une solution moins lourde...

    D'après toi, il n'est pas possible de faire autrement (en passant par getResource() ou un autre moyen tout aussi direct)??
    Ils flottent tous en bas

  11. #11
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    si le jar ne contient pas de code, le code de chargement se trouvera dans une autre jar. Donc la question que tu te dois te poser dans ce cas:

    Est-ce que mon jar dois pouvoir voir ces images? Si oui, alors mettre les jar-ressources dans les références classpath: du jar contenant le code faisant le chargement, et garder le même principe.

    Sinon, où suis-je supposé trouver les image? Dans "l'application courante"? Alors utiliser le classloader "courant" (accessible via Thread.getContextClassLoader).

    Pour donner deux exemples:

    Tu as besoin de charger une config base de donnée. Typiquement cette configuration sera fournie par l'application. Donc le contextClassLoader fera l'affaire.

    Tu as besoin de charger un bout de javascript qui n'est pas supposé être modifié indépendament de ton application, alors utiliser le classloader de la classe courante.


    Note que tu n'est pas lié à la classe, mais à son classloader, qui peut inclure de nombreux jar!

  12. #12
    Membre confirmé
    Profil pro
    Inscrit en
    Décembre 2003
    Messages
    476
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2003
    Messages : 476
    Points : 595
    Points
    595
    Par défaut
    Merci de ta réponse.
    Elle appelle une autre question
    Citation Envoyé par tchize_ Voir le message
    Est-ce que mon jar dois pouvoir voir ces images? Si oui, alors mettre les jar-ressources dans les références classpath: du jar contenant le code faisant le chargement, et garder le même principe.
    Tu entends quoi par mettre les jar-ressources dans les références classpath: du jar ?
    Ajouter dans l'attribut Class-Path du MANIFEST.MF le chemin vers le jar qui contient les fichiers ressources ou autre chose ?
    Ils flottent tous en bas

  13. #13
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    oui c'est ce que je voulais dire. Imaginons un jar avec un "theme", donc juste des images des des fichiers de config. Ton application qui utilise ce "theme" (donc le code qui aura besoin de charger) aura accès à ce thème via le MANIFEST.MF donc, c'est d'office dans le même classloader que le code, donc le classeloader de la classe du code fait l'affaire.

  14. #14
    Membre confirmé
    Profil pro
    Inscrit en
    Décembre 2003
    Messages
    476
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2003
    Messages : 476
    Points : 595
    Points
    595
    Par défaut
    Intéressant
    Je vais tester ça demain.
    Ils flottent tous en bas

  15. #15
    Membre régulier
    Inscrit en
    Avril 2008
    Messages
    184
    Détails du profil
    Informations personnelles :
    Âge : 48

    Informations forums :
    Inscription : Avril 2008
    Messages : 184
    Points : 90
    Points
    90
    Par défaut
    Merci pour toutes ces reponses.
    Bon j'ai trouvé mon problème : mon ant construisait mal mon Jar : il ne mettait pas les images . Du coup suivant si je compilais par netbeans ou par le ant je n'avais pas le meme resultat (d'où mon TU qui marchait mais pas mon application).

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Licence GPL Mysql et code source, dans une API externe
    Par guillaume-13015 dans le forum Administration
    Réponses: 4
    Dernier message: 28/11/2012, 19h14
  2. Appel Sipdroid dans une api android
    Par S.Jihad dans le forum Android
    Réponses: 0
    Dernier message: 16/05/2011, 12h54
  3. Réponses: 0
    Dernier message: 17/01/2011, 12h09
  4. Comment couper la fénétre principal dans une api windows
    Par ALF-Teams dans le forum Visual C++
    Réponses: 6
    Dernier message: 25/08/2006, 15h30
  5. faire un selection dans une image aves les APIs
    Par merahyazid dans le forum C++Builder
    Réponses: 3
    Dernier message: 30/04/2002, 10h44

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo