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

API standards et tierces Java Discussion :

[Classloader]mon progr ne marche plus après modif des *.class


Sujet :

API standards et tierces Java

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    52
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Décembre 2002
    Messages : 52
    Points : 52
    Points
    52
    Par défaut [Classloader]mon progr ne marche plus après modif des *.class
    Bonjour,
    Je me pose la question de savoir si l'on peut faire prudemment des patches d'une appli en fournissant uniquement les classes qui ont été modifiées.

    Voici mon problème plus en détail.
    J'ai développé un client lourd java que j'ai livré à un département chargé d'en faire des fichiers d'installation *.msi pour installation sur les postes des utilisateurs (vous allez, dire que c'est con de faire des *.msi alors qu'on peut déployer aisément avec Java web Start, mais voyez-vous, c'est pas moi qui décide ce genre de choses .....).
    Bref, revenons à nos moutons :
    Une fois que les *.msi sont réalisés et déployés sur les postes des testeurs et que certains bugs sont signalés, Le client pour qui je travaille m'impose de liver des "patches" consititués uniquement des *.class correspondant aux sources que j'ai modifiés lors de la correction des bugs.

    Je suis contre ce principe parce que je pense qu'il peut arriver que des classes qui n'ont pas été compilées ensembles ne marchent pas bien.

    D'ailleurs, il y a depuis 2 jours un nouveau bug est apparu après la livraison d'un de ces patches. Ce bug ne se produit pas sur mon poste parce que justement (selon moi) mes classes ont été compilées ensembles.
    Le bug en question est que l'URL d'un fichier de config n'a pas pu être construite.
    Le code dont je me sers pour pour charger ce fichier de conf a toujours marché. Ce code renvoie un objet de type java.net.URL. C'est le code suivant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    this.getClass().getClassLoader().getResource(configFileFullPath)
    où configFileFullPath est un String représentant le chemin du fichier à partir de la racine des package, par exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    "com/mycompany/project/aspect/config.xml"
    Savez-vous si j'ai raison ?
    Est-ce que de façons générale (en dehors de RMI) des classes qui n'ont pas été compilées ensembles peuvent conduire -au moment de l'exécution- à un comportement erroné ? Pourriez-vous argumentez votre avis par des exemples ?
    Avez-des références à ce propos que je peux consulter sur le net ?
    Merci
    ----------------------------------
    Let the feast, start !
    Vitamines pour l'esprit : http://www.batisseurs-de-succes.com/

  2. #2
    Membre expérimenté Avatar de yann2
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2004
    Messages
    897
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2004
    Messages : 897
    Points : 1 635
    Points
    1 635
    Par défaut
    bonjour

    Ben non ! Le fonctionnement ne peut être erroné (sauf pour les pb de versions dont tu parles dans un contexte RMI).

    Exemple :
    - Quand tu codes, tu ne recompiles pas tous le JDK !
    - Tu utilises toujours des libs externes que tu ne recompiles jamais !

    Bref, je pense que ça devrait fonctionner...

    Mais bon...

  3. #3
    Membre confirmé Avatar de Satch
    Homme Profil pro
    Hypnothérapeute - Magicien
    Inscrit en
    Mars 2004
    Messages
    498
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : Suisse

    Informations professionnelles :
    Activité : Hypnothérapeute - Magicien

    Informations forums :
    Inscription : Mars 2004
    Messages : 498
    Points : 645
    Points
    645
    Par défaut
    Citation Envoyé par yann2
    Bref, je pense que ça devrait fonctionner...
    Mais bon...
    Tu penses ? Pas très convaincant comme réponse ça.

    J'avoue que la question m'interresse aussi.

    Je me demande si le compilateur ne ferait pas quelques optimisations.

    J'aimerai beaucoup que quelqu'un puisse dire catégoriquement si oui ou non on peut juste donner les .class qui ont changé.
    Je sais que désormais vivre est un calembour,
    La mort est devenue un état permanent,
    Le monde est aux fantômes, aux hyènes et aux vautours.
    Moi je vous dis bravo et vive la mort.

  4. #4
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    52
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Décembre 2002
    Messages : 52
    Points : 52
    Points
    52
    Par défaut
    Je suis d'accord avec Satch.
    J'aurais souhaité une réponse plus précise et si possible avec des références disponibles sur le net, par exemple.
    ----------------------------------
    Let the feast, start !
    Vitamines pour l'esprit : http://www.batisseurs-de-succes.com/

  5. #5
    Membre confirmé Avatar de Scorpyosis
    Homme Profil pro
    Inscrit en
    Janvier 2004
    Messages
    365
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2004
    Messages : 365
    Points : 570
    Points
    570
    Par défaut
    Moi je suis de l'avis de yann2, je ne vois pas en quoi le fait de compiler les classes de façon séparément les rendraient inutilisable, ca va à l'encontre du bon sens. Comme le fait remarquer yann2, vous n'avez pas a recomplier tout le jdk pour pouvoir l'utiliser ! Si on suit votre idée, si on veut utiliser une lib il faut avoir les sources, sinon ca ne marcherait pas...etrange non ?! Quand au compilo, il fait certes des optimisation mais rien dans ce genre, sinon ca deviendrait ingérable. Quand a ton probleme es tu sur que vos environnement de travail soit les meme ? meme arborescence de fichier ?
    Les deux principales inventions sorties de Berkeley sont UNIX et le LSD. Difficile de croire à une quelconque coïncidence - Jeremy S. Anderson

    Avant de vouloir qu’un logiciel soit réutilisable, il faudrait d’abord qu’il ait été utilisable - Ralph Johnson

  6. #6
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2005
    Messages
    109
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2005
    Messages : 109
    Points : 122
    Points
    122
    Par défaut
    Il faut quand même s'assurer que les nouveaux binaires soient compatibles avec l'environnement d'exécution et peut-être bien aussi avec les anciens.

    Melchisedec, tu n'as pas une trace ?

  7. #7
    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,

    Citation Envoyé par Scorpyosis
    Moi je suis de l'avis de yann2, je ne vois pas en quoi le fait de compiler les classes de façon séparément les rendraient inutilisable, ca va à l'encontre du bon sens.
    Il y a un cas ou cela peut poser problème : si on utilise des constantes avec des types primaires ou des String, par exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    public class Constante {
        public static final String NOM = "valeur";
        public static final int INTKEY = 0;
    }
    En effet lorsqu'on utilise une de ces constantes dans une autre classe, le lien avec la classe Constante est perdu à la compilation, ainsi le code suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    System.out.println(Constante.NOM);
    System.out.println(Constante.INTKEY);
    Est compilé de la mnière suivante (les références sotn remplacé par leurs valeurs) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    System.out.println("valeur");
    System.out.println(0);
    De ce fait, si les valeurs des contantes sont modifiées, toutes les classes qui utilisent ces constantes doivent être recompilé...

    Nota: Si on utilise des objets il n'y a pas de remplacement, la référence est bien conservé à la compilation...


    Est-ce que c'est ton cas ???

    a++

  8. #8
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    52
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Décembre 2002
    Messages : 52
    Points : 52
    Points
    52
    Par défaut
    Citation Envoyé par Scorpyosis
    Si on suit votre idée, si on veut utiliser une lib il faut avoir les sources, sinon ca ne marcherait pas...etrange non ?!
    Je crois que tu n'as pas bien saisi, Scorpyosis. Les classes d'une lib ont déja été compilées ensemble. Quand tu te sers d'une lib, tu ne fais qu'importer les classes de cette lib et t'en servir.

    Or ici, je parle de modifier quelques sources de mon projet, les recompiler et livrer aux utilisateurs seulement les *.class des sources modifiés de sorte que ces *.class remplacent leurs anciennes version. On retrouvent alors chez les utilisateurs un ensemble de classes qui n'ont pas été compilées ensemble.
    De toute façon, je souhaiterais avoir des réponses plus précises qu'une simple opinion basée sur le bon sens. L'idée bon sens est quelque chose de très personnel.
    Avez-vous des références reconnues où une explication plus rigoureuse ?
    ----------------------------------
    Let the feast, start !
    Vitamines pour l'esprit : http://www.batisseurs-de-succes.com/

  9. #9
    Membre habitué Avatar de Xavinou
    Inscrit en
    Mai 2005
    Messages
    135
    Détails du profil
    Informations forums :
    Inscription : Mai 2005
    Messages : 135
    Points : 156
    Points
    156
    Par défaut
    Est ce que tu es sur que le code livré par le département chargé du deployement n'est pas offusqué ?

    Sinon il n'y a pas de raison que tes nouvelles classes ne marchent pas, sauf (bien sûr) si leurs interfaces ont été modifiées.

  10. #10
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    52
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Décembre 2002
    Messages : 52
    Points : 52
    Points
    52
    Par défaut
    Je ne peux vous donner tout le code pour des raisons de secret professionel mais voici le constructeur qui pose problème :

    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
     private MDMRConfigurator(String configFileFullPath, String natCo) {
            currentNatco = natCo;
            //TODO gérer les user groups
            currentUserGroup = "";
            applConfigFileFullPath = configFileFullPath;
            try {
                com.airbus.mdmr.config.xmlprocessor.ObjectFactory jaxbContext = new com.airbus.mdmr.config.xmlprocessor.ObjectFactory();
     
                xmlMdmConfig = (MdmConfig) mdmUnmarshaller
                        .unmarshal(getClass().getClassLoader().getResource(configFileFullPath));
                TabListFactory
                        .initFactory("com/airbus/mdmr/config/resource/tabbedtreepane-config.xml");
                localUserPreferences = Preferences.userRoot();
                if (xmlMdmConfig != null) {
                    retrieveConfigInformation(xmlMdmConfig);
                } else {
                    logger.error("Error while reading the config.xml file");
                    //TODO erro message
                    System.exit(1);
                }
            } catch (Exception e) {
                // TODO Auto-generated catch block
                logger.error(e.getMessage(), e);
            }
     
        }
    La ligne qui déclenche le problème est la seconde instruction à l'intérieur du try-catch :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    xmlMdmConfig = (MdmConfig) mdmUnmarshaller
                        .unmarshal(getClass().getClassLoader().getResource(configFileFullPath));
    La trace est :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    2006-04-27 14:12:05,615 [main] ERROR (MDMRConfigurator.java:389) - url parameter
     must not be null
    java.lang.IllegalArgumentException: url parameter must not be null
            at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnm
    arshallerImpl.java:141)
            at com.airbus.mdmr.config.MDMRConfigurator.<init>(MDMRConfigurator.java:
    375)
            at com.airbus.mdmr.config.MDMRConfigurator.getInstance(MDMRConfigurator.
    java:349)
            at com.airbus.mdmr.launcher.MainClass.main(MainClass.java:291)
    Et dans cette trace, la ligne 375 correspond bien à la ligne incriminée dont je parle ci-dessus.
    ----------------------------------
    Let the feast, start !
    Vitamines pour l'esprit : http://www.batisseurs-de-succes.com/

  11. #11
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    52
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Décembre 2002
    Messages : 52
    Points : 52
    Points
    52
    Par défaut
    Citation Envoyé par Xavinou
    Est ce que tu es sur que le code livré par le département chargé du deployement n'est pas offusqué ?
    T'inquiète pas, ces gars ne savent même pas ce que c'est que l'offuscation.
    ----------------------------------
    Let the feast, start !
    Vitamines pour l'esprit : http://www.batisseurs-de-succes.com/

  12. #12
    Membre régulier
    Profil pro
    Inscrit en
    Avril 2006
    Messages
    85
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2006
    Messages : 85
    Points : 81
    Points
    81
    Par défaut
    Salut,

    Je n'ai pas spécialement d'expérience avec ce genre de manipulation,
    mais si l'on part du principe qu'un jar est un ensemble de fichier .class et
    l'on peut les utiliser sans avoir eu à les compiler soit-même, je pense que
    ca ne devrait pas poser de problème de remplacer un .class dans un
    répertoire. Par exemple, sur un serveur tomcat, dans le repertoire
    WEB-INF/classes/ on peut très bien mettre la mise à jour d'une classe
    sans pour autant avoir à recompiler toute l'application.
    Du coup, je pencherais plutôt pour un vrai bug :-(

    Parcontre, attention, parce que des fois, les clients quand on leur fournit
    un nouveau fichier jar à mettre dans leur WEB-INF/lib, ils renomment
    l'ancien et mettent le nouveau, seulement si l'ancien et chargé avant,
    ben ton nouveau .jar est pas pris en charge !!! genre toto.jar devient
    ancien_toto.jar, sera chargé avant le nouveau toto.jar.

    Voilà bon débuggage !
    a+
    Xavier

  13. #13
    Membre expert

    Homme Profil pro
    Consultant informatique
    Inscrit en
    Janvier 2004
    Messages
    2 301
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : Finance

    Informations forums :
    Inscription : Janvier 2004
    Messages : 2 301
    Points : 3 675
    Points
    3 675
    Par défaut
    Oui, on peut remplacer un .class par un autre du même nom, sans rencontrer de problème, pour autant que les 2 versions soient compatibles entre elles...

    Petite parenthèse: pour assurer la compatibilité ascendante de ses API, Sun garantit de ne jamais supprimer de fonctionnalité à aucune classe: au pire, certaines parties d'une classe deviennent "deprecated" d'une version à l'autre, c'est-à-dire déconseillées, mais peuvent quand même être utilisées... ainsi, un fichier .class plus récent peut toujours être utilisé avec le reste de l'architecture antérieur...
    "Le plug gros problème des citations trouvées sur internet, c'est qu'on ne peut jamais garantir leur authenticité"

    Confucius, 448 av. J-C

  14. #14
    Membre confirmé Avatar de Scorpyosis
    Homme Profil pro
    Inscrit en
    Janvier 2004
    Messages
    365
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2004
    Messages : 365
    Points : 570
    Points
    570
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    getClass().getClassLoader().getResource(configFileFullPath)
    Ceci renvoit null, donc configFileFullPath doit pas etre bon. Utilise finResource(configFileFullPath) pour tester s'il trouve ton fichier.
    Les deux principales inventions sorties de Berkeley sont UNIX et le LSD. Difficile de croire à une quelconque coïncidence - Jeremy S. Anderson

    Avant de vouloir qu’un logiciel soit réutilisable, il faudrait d’abord qu’il ait été utilisable - Ralph Johnson

  15. #15
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    52
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Décembre 2002
    Messages : 52
    Points : 52
    Points
    52
    Par défaut
    Citation Envoyé par Scorpyosis
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    getClass().getClassLoader().getResource(configFileFullPath)
    Ceci renvoit null, donc configFileFullPath doit pas etre bon. Utilise finResource(configFileFullPath) pour tester s'il trouve ton fichier.
    Oui, effectivement, il se peut que le String configFileFullPath ne soit pas bon. Il se peut que celui quelqu'un ait commis une erreur à un moment donné.
    Mais je pense que le code source est bon. Il a toujours marché, il marche sur mon poste donc il n'y a pas de raison qu'il ne marche pas ailleurs.


    Par ailleurs si j'ai bonne mémoire, la méthode ClassLoader.getResource() fait appelle à findResource. Je vais quand-même tester ce que tu me propose mais je pense que l'erreur ne vient pas de là.

    Enfin, il n'y a toujours pas de réponse franche et claire à ma question initiale. Je souhaite qu'il n'y ait pas de réponse basée sur des suppositions mais je recherche une réponse rigoureuse à mes questions initiales.

    Merci
    ----------------------------------
    Let the feast, start !
    Vitamines pour l'esprit : http://www.batisseurs-de-succes.com/

  16. #16
    Membre confirmé Avatar de Scorpyosis
    Homme Profil pro
    Inscrit en
    Janvier 2004
    Messages
    365
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2004
    Messages : 365
    Points : 570
    Points
    570
    Par défaut
    Dispose tu du fichier d'install qui a été fait ? le plus simple reste de faire une installation et de tester si il y a des différences entre ton poste de développement et un poste client ou l'install a été faite. Je ne remets pas en cause ton code source mais je penche plutot a une arborescence/config qui a été mal faite...
    Les deux principales inventions sorties de Berkeley sont UNIX et le LSD. Difficile de croire à une quelconque coïncidence - Jeremy S. Anderson

    Avant de vouloir qu’un logiciel soit réutilisable, il faudrait d’abord qu’il ait été utilisable - Ralph Johnson

  17. #17
    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
    Citation Envoyé par Melchisedec
    Enfin, il n'y a toujours pas de réponse franche et claire à ma question initiale. Je souhaite qu'il n'y ait pas de réponse basée sur des suppositions mais je recherche une réponse rigoureuse à mes questions initiales.
    Alors il faut nous donner plus de détail... Ce n'est pas avec un bout de code et une exception null qu'on pourra trouver ton problème !!!

    Comme il semble que ce soit la méthode getResource() qui renvoit null, vérifie la valeur de configFileFullPath et la manière dont elle est récupéré chez toi et chez le client...

    a++

Discussions similaires

  1. Mon projet n'accepte plus les modifications
    Par bache dans le forum VB.NET
    Réponses: 8
    Dernier message: 13/11/2007, 08h27
  2. Mon programme ne fonctionne plus après mise à jour de linux
    Par dybmans dans le forum GTK+ avec C & C++
    Réponses: 22
    Dernier message: 06/05/2007, 18h08
  3. Mon programme ne marche pas aprés le if:?
    Par mitherkiller dans le forum C
    Réponses: 28
    Dernier message: 28/03/2007, 19h47
  4. [Support]Mon ordi ne repond plus apres mise en veille
    Par Nip dans le forum Ordinateurs
    Réponses: 11
    Dernier message: 22/03/2007, 14h22
  5. [.net] keypress marche plus après click
    Par noinneh dans le forum MFC
    Réponses: 1
    Dernier message: 24/02/2006, 16h45

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