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 :

exemple du FAQ inexacte [FAQ]


Sujet :

Java

  1. #1
    Membre à l'essai
    Inscrit en
    Juin 2005
    Messages
    20
    Détails du profil
    Informations forums :
    Inscription : Juin 2005
    Messages : 20
    Points : 10
    Points
    10
    Par défaut exemple du FAQ inexacte
    cet exemple :
    http://java.developpez.com/faq/java/...YSTEME_dir_jar
    pour trouver le repertoire contenant cette classe ne marche par car

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    URL url = getClass().getResource(path);
    retourne , que ce soit sous eclipse ou directement avec le shell

    NB : je suis en static, j'ai donc remplacé par PS : cette méthode est appelée au chargement de la classe car elle avec tout de suite une constante de type public static final

  2. #2
    Rédacteur
    Avatar de bulbo
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Février 2004
    Messages
    1 259
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : Finance

    Informations forums :
    Inscription : Février 2004
    Messages : 1 259
    Points : 1 937
    Points
    1 937
    Par défaut
    C'est quoi exactement qui ne marche pas ?

    Si c'est juste le getClass a remplacer par Start.class alors lit juste la reponse jusqu'a la fin, specialement le NB2.

    Bulbo

  3. #3
    Membre à l'essai
    Inscrit en
    Juin 2005
    Messages
    20
    Détails du profil
    Informations forums :
    Inscription : Juin 2005
    Messages : 20
    Points : 10
    Points
    10
    Par défaut
    j'ai bien remplacé le getClass() par Start.class (je l'ai précisé)

    ce qui fonctionne pas c'est
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    URL url = getClass().getResource(path);
    car url = null

    le ClassLoader ne trouve pas la ressource, certainement car l'affectation ce fait lors du chargement (la methode affecte un final static, comme si on mettait un bloc static{} dans une classe), et qu'on lui demande une info alors qu'il n'a pas terminé le chargement.

    mais j'ai trouvé la solution qui marche tres bien (je passe pas la localisation du code source)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
     
    String path = "If you read this, there is a serious problem, correct the code (osteo/Start.java)";
            try {
                String qualifiedClassName = Start.class.getName();
                Class qc = Class.forName( qualifiedClassName );
                CodeSource source = qc.getProtectionDomain().getCodeSource();
                if ( source != null ) {
                    URL location = source.getLocation();
                    System.out.println ( qualifiedClassName + " : " + location );
                    path = URLDecoder.decode(location.toString(), "UTF-8");
                } else {
                    System.out.println ( qualifiedClassName + " : " + "unknown source, likely rt.jar" );
                }
            } catch ( Exception e ) {
                System.err.println( "Unable to locate class on command line." );
                e.printStackTrace();
            }
    je n'ai trouvé aucun cas où il ne fonctionne pas (class ou jar, dans le dossier courant ou à l'exterieur, static ou non)

    la soucre (le meilleur tuto sur les classpath que j'ai trouvé, il est fortement conseillé)
    http://mindprod.com/jgloss/classpath.html

    à reprendre pour completer le FAQ (en reliant au site source, il a beaucoup d'info)

  4. #4
    Membre à l'essai
    Inscrit en
    Juin 2005
    Messages
    20
    Détails du profil
    Informations forums :
    Inscription : Juin 2005
    Messages : 20
    Points : 10
    Points
    10
    Par défaut
    ah mais bulbo c'est toi l'auteur de ce FAQ.
    Si tu veux des exemples de ce qui fonctionne et ne fonctionne pas, je te passe les sources (simplifiée) avec un petit script shell (Linux).
    Je suis content de pouvoir contribuer au FAQ plus qu'util (si la solution est acceptée)

  5. #5
    Rédacteur
    Avatar de bulbo
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Février 2004
    Messages
    1 259
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : Finance

    Informations forums :
    Inscription : Février 2004
    Messages : 1 259
    Points : 1 937
    Points
    1 937
    Par défaut
    Desole mais chez moi ca marche, depuis un bloc static ou non.

    Le fait que la classe ne soit pas completement charge n'empeche pas le ClassLoader de trouver la classe.

    Voici mon test qui fonctionne:

    Compile et execute tel quel depuis eclipse et le repertoire est bien trouve.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
     
    import java.net.URL;
    import java.net.URLDecoder;
     
     
    public class TestLocation
    {
     
      static
      {
        try
        {
          String path = TestLocation.class.getName() + ".class";
          URL url = TestLocation.class.getResource(path);
          path = URLDecoder.decode(url.toString(), "UTF-8");
          // suppression de  la classe ou du jar du path de l'url
          int index = path.lastIndexOf("/");
          path = path.substring(0, index);
          if (path.startsWith("jar:file:"))
          {
            // suppression de jar:file: de l'url d'un jar
            // ainsi que du path de la classe dans le jar
            index = path.indexOf("!");
            path = path.substring(9, index);
          }
          else
          {
            // suppresion du file: de l'url si c'est une classe en dehors d'un jar
            // et suppression du path du package si il est présent.
            path = path.substring(5, path.length());
            Package pack = TestLocation.class.getPackage();
            if (null != pack)
            {
              String packPath = pack.toString().replace('.', '/');
              if (path.endsWith(packPath))
              {
                path = path.substring(0, (path.length() - packPath.length()));
              }
            }
          }
          System.out.println("Répertoire contenant la classe: " + path);
        }
        catch (Exception e)
        {
          e.printStackTrace();
        }
      }
     
      public static void main(String[] args)
      {}
    }
    Tu pourrais montrer le code que tu utilises et qui ne marche pas ? Et aussi preciser le contexte d'execution (appli java, applet, servlet, server d'application .. ?)

    Et aussi si c'est dans un jar, war ou directement dans un repertoire..

    Merci,

    Bulbo

  6. #6
    Membre à l'essai
    Inscrit en
    Juin 2005
    Messages
    20
    Détails du profil
    Informations forums :
    Inscription : Juin 2005
    Messages : 20
    Points : 10
    Points
    10
    Par défaut
    tiens, c'est bizarre, ca marche pas chez moi

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    package osteo;
     
    import java.net.URL;
    import java.net.URLDecoder;
     
     
    /**
     * @author
     *
     */
    public class TestLocation
    {
     
      static
      {
        try
        {
          String path = TestLocation.class.getName() + ".class";
          URL url = TestLocation.class.getResource(path);
          path = URLDecoder.decode(url.toString(), "UTF-8");
          // suppression de  la classe ou du jar du path de l'url
          int index = path.lastIndexOf("/");
          path = path.substring(0, index);
          if (path.startsWith("jar:file:"))
          {
            // suppression de jar:file: de l'url d'un jar
            // ainsi que du path de la classe dans le jar
            index = path.indexOf("!");
            path = path.substring(9, index);
          }
          else
          {
            // suppresion du file: de l'url si c'est une classe en dehors d'un jar
            // et suppression du path du package si il est présent.
            path = path.substring(5, path.length());
            Package pack = TestLocation.class.getPackage();
            if (null != pack)
            {
              String packPath = pack.toString().replace('.', '/');
              if (path.endsWith(packPath))
              {
                path = path.substring(0, (path.length() - packPath.length()));
              }
            }
          }
          System.out.println("Répertoire contenant la classe: " + path);
        }
        catch (Exception e)
        {
          e.printStackTrace();
        }
      }
     
      /**
     * @param args
     */
      public static void main(String[] args)
      {
          new TestLocation();
      }
    }
    si je le lance sous eclipse :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    java.lang.NullPointerException
        at osteo.TestLocation.<clinit>(TestLocation.java:20)
    sous le shell :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    kevredon@kotori:~/stage/prog/oscar_scilab_2d/bin$ java osteo.TestLocation
    java.lang.NullPointerException
            at osteo.TestLocation.<clinit>(TestLocation.java:20)
    c'est curieux ça, il m'aime peut etre pas

    PS : tant que tu ne fais pas allusion à cette classe dans ton code, le ClassLoader ne la chargera pas (c'est pour ca que j'ai mis : new TestLocation())

    Mon programme original c'est la meme chose (hierarchie), mais avec la solution alternative ca marche (sous jar, ou direct dans le dossier bin)
    Je tourne sous eclipse 3.2, JRE1.5.05, Ubuntu Dapper Drake

  7. #7
    Rédacteur
    Avatar de bulbo
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Février 2004
    Messages
    1 259
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : Finance

    Informations forums :
    Inscription : Février 2004
    Messages : 1 259
    Points : 1 937
    Points
    1 937
    Par défaut
    Et bien tu avais raison la FAQ etait bien inexacte et elle sera corrigee.

    En fait c'est du au package, je pensais que getName ne retournait que le nom de la classe mais en fait il retourne le nom avec le package en prime.

    La premiere ligne est a changer par celle la:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    String path = "/" + TestLocation.class.getName().replace('.', '/') + ".class";
    Voila comme ca plus de probleme.

    Bulbo

  8. #8
    Membre régulier
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    115
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : Belgique

    Informations forums :
    Inscription : Septembre 2003
    Messages : 115
    Points : 77
    Points
    77
    Par défaut
    moi je m'y connais pas trop avec les URL et co
    mais j'ai essayé avec une classe dans un répertoires et un accès static et j'ai aussi l'erreur de la NullPointerException au niveau de l'url


    voila si ca peut vous être utile,

    Pour infos eclipse 3.1
    J2SE 1.5_06
    Win Xp



    voila a++


    EDIT : Sorry je n'avais pas vu que bulbo venait de poster un message au même moment

  9. #9
    Membre à l'essai
    Inscrit en
    Juin 2005
    Messages
    20
    Détails du profil
    Informations forums :
    Inscription : Juin 2005
    Messages : 20
    Points : 10
    Points
    10
    Par défaut
    je pensais qu'il remplacait tout seul les "." par "/"

    http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Class.html#getResource(java.lang.String)


    maintenant ca marche, mais il reste un mini detail, c'est qu'il ajoute aussi le chemin du packet (Répertoire contenant la classe: /home/kevredon/stage/prog/oscar_scilab_2d/bin/osteo)
    Je pense qu'il faut le virer (si on veut la racine du programme java, et non le dossier de la classe)

  10. #10
    Expert éminent sénior
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Salut,


    Il s'agit surement d'un problème de package...

    getResource() renvoit une URL selon les cirtère suivant :
    • Si le chemin passé en paramètre commence par un '/', alors le chemin absolu est inchangé,
    • Sinon, le nom du package de la Class depuis lequel getResource est appellé est rajouté devant le nom.
    Pour le code suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    String path = TestLocation.class.getName() + ".class";
    URL url = TestLocation.class.getResource(path);
    bulbo ne semble pas utilisé de package, donc cela revient à :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    URL url = TestLocation.class.getResource("/" + "TestLocation.class");
    Ce qui est correcte puisque comme TestLocation n'appartient pas à un package, il est à la racine de l'arborescence logique représenté par le classpath.

    kevredon utilise au contraire un package nommé "osteo", donc chez lui cela devient :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    URL url = TestLocation.class.getResource("/osteo/" + "osteo.TestLocation.class");
    Et du coup on a le nom du package en trop dans le nom du fichier... Il faudrait utiliser Class.getSimpleName() de Java 5.0 pour éviter ce problème...

    Ou bien créer soi même le chemin absolu en ajoutant le / au début et en remplacant tout les "." du nom de la classe par des / :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    String path = "/" + TestLocation.class.getName().replaceAll("\\.", "/") + ".class";
    Perso j'utilise le code suivant pour récupérer le fichier contenant le bytecode (*.class, *.jar ou *.zip) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
        public static File getByteCodeFile(Class c) {
            File result = null;
            URL url = c.getResource("/" + c.getName().replaceAll("\\.", "/") + ".class");
     
            // Théoriquement on ne devrait jamais avoir null :
            if (url!=null) {
                try {
                    if ("jar".equals(url.getProtocol()) ) {
                        String path = url.getPath();
                        int idx = path.lastIndexOf('!');
                        if (idx>0) {
                            path = path.substring(0, idx);
                        }
                        url = new URL(path); // MalformedURLException
                    }
                    result = new File(url.getPath());
                } catch (MalformedURLException e) {
                    // Normalement on ne devrait jamais passer dans ce catch
                    e.printStackTrace();
                }
            }
            return result;
        }
    a++

    PS : je viens de voir en prévisualisant que vous avez trouvé l'origine du problème... je poste quand même si ca interresse quelqu'un...

  11. #11
    Rédacteur
    Avatar de bulbo
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Février 2004
    Messages
    1 259
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : Finance

    Informations forums :
    Inscription : Février 2004
    Messages : 1 259
    Points : 1 937
    Points
    1 937
    Par défaut
    Les '.' sont remplacer par des '/' mais seulement depuis le jdk 1.5 il semblerait.

    Et effectivement il y avait un autre bug. Remplace la ligne ou est cree packPath par celle ci:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    String packPath = pack.getName().replace('.', '/');
    Le toString de package retourne "package tonPackage" .. il semblerait que je n'avais pas teste ce code avec une classe dans un package moi

    [Edit pour AdiGuba] Comme on propose une solution portable pour les differentes version de JVM je preferre utiliser replace que replaceAll dispo que depuis la 1.4.

    Surtout que dans ce cas precis elles font exactement la meme chose.
    [/Edit]

    Bulbo

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

Discussions similaires

  1. Exemple QProcess FAQ: aide compréhension
    Par Nykoo dans le forum Qt
    Réponses: 9
    Dernier message: 01/04/2008, 00h28
  2. Question sur une condition d'un exemple de la FAQ
    Par Bleys dans le forum Delphi
    Réponses: 3
    Dernier message: 08/08/2006, 12h43
  3. L'exemple des thread de la FAQ ne marche pa chez moi
    Par mcdonald dans le forum Général Python
    Réponses: 2
    Dernier message: 10/06/2006, 14h47
  4. Récup des données d'un select (cf exemple dans la faq)
    Par j0k3r_n0ir dans le forum Général JavaScript
    Réponses: 5
    Dernier message: 28/02/2005, 18h36

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