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

AWT/Swing Java Discussion :

[loadClass] java.lang. NoClassDefFoundError


Sujet :

AWT/Swing Java

  1. #1
    Membre éclairé
    Inscrit en
    Décembre 2005
    Messages
    251
    Détails du profil
    Informations forums :
    Inscription : Décembre 2005
    Messages : 251
    Par défaut [loadClass] java.lang. NoClassDefFoundError
    Bonjour,

    J'ai réalisé un chargeur de fichier jar. Il charge les class contenu dans le fichier jar puis execute la méthode main.
    J' ai test mon programme sur 2 class. L'une extends de JFrame et L'autre de JPanel. Je fais un appelle du panel dans ma frame. Tout ce passe bien!
    Quand je reproduit l'opération sur un programme plus gros (plus de class) au moment d'executer la méthode main l'erreur suivante apparait :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    Trowable 2 java.lang.reflect.InvocationTargetException
    Trowable 2 getCause java.lang.NoClassDefFoundError: JPanelImage
    Trowable 2 getMessage null
    Trowable 2 getStackTrace() [Ljava.lang.StackTraceElement;@1bab50a
    Ce que je ne comprends pas : c'est que la class JPanelImage a été déjà chargée. Donc je ne comprends pas pourquoi il cherche à faire une recharge.

    Merci de votre aide.

  2. #2
    Membre éclairé
    Inscrit en
    Décembre 2005
    Messages
    251
    Détails du profil
    Informations forums :
    Inscription : Décembre 2005
    Messages : 251
    Par défaut
    Pour preciser ce que j'ai fait,

    Ma class chargeur extends de LoaderClass et surcharge la méthode findClass.
    Ce qui fait que lorsque j'utilise la méthode load les chargeur "naturels" cherche les fichier en .class s'ils ne les trouvent pas, alors il y a utilisation de la surcharge.
    Dans mon cas le byte code a été crypté donc il ne posséde pas la même extention (.crypt). C'est pour cela que je doit utiliser un chargeur de class.

    Bref, l'erreur qui sort est comme si lors de l'execusion de la class possédant le main il cherche à charger un fichier.class alors que la class a déjà été chargée, comme s'il ne voyait pas ou avait oublier que la class été déjà chargée.

    Donc serait-il possible d'avoir trop charger de choses et qu'il y ait un écrasement dans la machine virtuelle des class chargées ?

  3. #3
    Rédacteur
    Avatar de pseudocode
    Homme Profil pro
    Architecte système
    Inscrit en
    Décembre 2006
    Messages
    10 062
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Architecte système
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2006
    Messages : 10 062
    Par défaut
    C'est cool de voir que ton projet de cryptage avance...

    Citation Envoyé par philippe13
    Donc serait-il possible d'avoir trop charger de choses et qu'il y ait un écrasement dans la machine virtuelle des class chargées ?
    Heu.. non je ne pense pas!
    Ou alors va falloir que je me repenche sur mon code !

    Comment tu charges ta classe en utilisant ton classloader ? (as-tu bien mis le bollean resolve a TRUE ?)
    ALGORITHME (n.m.): Méthode complexe de résolution d'un problème simple.

  4. #4
    Membre éclairé
    Inscrit en
    Décembre 2005
    Messages
    251
    Détails du profil
    Informations forums :
    Inscription : Décembre 2005
    Messages : 251
    Par défaut
    Salut,

    as-tu bien mis le bollean resolve a TRUE ?
    Heu... je sais pas.

    voici mon code :
    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
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
     
     public LanceurRadar()
        {
            String[] args = new String[] {};
            Method m = null;
            Method m1 = null;
            boolean me;
            try{
                    System.out.println("initialisation");
                    String Main = null;
                    Class cl = null;
                    Object clas;
     
     
                    ClassLoader loader = new LoaderCrypt("C:\\Documents and Settings\\DELL2\\Bureau\\secret.key",
                    "C:\\Documents and Settings\\DELL2\\Bureau\\AES\\MonjarCrypt.jar");
     
                    JarFile jar = new JarFile("C:\\Documents and Settings\\DELL2\\Bureau\\AES\\MonjarCrypt.jar");
    //on rempli l'enumeration cela nous permettra de récuperer le nom des class
                    Enumeration E = jar.entries();
                    clas = E.nextElement();
     
                    System.out.println("boucle while");
     
                        while(true)
                        {
                            me = true;
    //on ne prend que les fichiers ayant l'extention .AES
                            if(clas.toString().substring(clas.toString().length()-4,clas.toString().length()).equals(".AES"))
                            {
                            E.hasMoreElements();
                            String s = clas.toString().substring(0,clas.toString().length()-4);
                            System.out.println(s);
                            cl = loader.loadClass(s+"jar");
                            try{
                            m = cl.getMethod("main",  args.getClass());
                            }
    //si m est vide une exeption sera levée 
                            catch(NoSuchMethodException ed){me = false;}
                            if(me)
                            {
                                System.out.println("methode "+m);
                                m1 = m;
                                m1 = cl.getMethod("main", args.getClass());
                            }
                            System.out.println("fichier .class suivant");
                            clas = E.nextElement();
                            }
                            else{
                                System.out.println("fichier suivant");
                                clas = E.nextElement();
                            }
                        }
     
     
                }
             catch(Throwable e){System.out.println("Trowable "+e);}
     
            //à la fin on exécute la méthode main
            try{
                System.out.println("runClass3");
                m1.invoke(null, (Object) args);
                System.out.println("runClass4");
            }
            catch(Throwable e)
            {
                System.out.println("Trowable 2 "+e);
                System.out.println("Trowable 2 getCause "+e.getCause());
                System.out.println("Trowable 2 getMessage "+e.getMessage());
                System.out.println("Trowable 2 getStackTrace() "+e.getStackTrace());
            }
        }

  5. #5
    Rédacteur
    Avatar de pseudocode
    Homme Profil pro
    Architecte système
    Inscrit en
    Décembre 2006
    Messages
    10 062
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Architecte système
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2006
    Messages : 10 062
    Par défaut
    essaye ca...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
       cl = loader.loadClass(s+"jar",true);
    ALGORITHME (n.m.): Méthode complexe de résolution d'un problème simple.

  6. #6
    Membre éclairé
    Inscrit en
    Décembre 2005
    Messages
    251
    Détails du profil
    Informations forums :
    Inscription : Décembre 2005
    Messages : 251
    Par défaut
    salut,

    mon problème est que loadClass (String name, boolean resolve) est protected. Ce qui m'arrage pas. J'ai surcharger la méthode loadClass de la manière suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    public Class loadClass(String name)
                    throws ClassNotFoundException
        {
            return loadClass(name, true);
        }
    Il y a du mieux mais quelques problème reste :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
            at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
            at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
            at java.lang.reflect.Method.invoke(Method.java:585)
     
    et
     
    Trowable 2 java.lang.reflect.InvocationTargetException
    Trowable 2 getCause java.lang.LinkageError: loader constraints violated when linking JPanelImage class
    Trowable 2 getMessage null
    Trowable 2 getStackTrace() [Ljava.lang.StackTraceElement;@170bea5
    Ce coup ci, il y a eu un mieux puisque la JPanelImage a été lancée.

    Crois tu qu'il serait possible d'utiliser setContextClassLoader(ClassLoader loader) dans mon thread général afin que toutes les class appelées par le bon chargeur, même celles appelées dans les class appelées dans le thread (appelle secondaire) ?

  7. #7
    Rédacteur
    Avatar de pseudocode
    Homme Profil pro
    Architecte système
    Inscrit en
    Décembre 2006
    Messages
    10 062
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Architecte système
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2006
    Messages : 10 062
    Par défaut
    Citation Envoyé par philippe13
    Crois tu qu'il serait possible d'utiliser setContextClassLoader(ClassLoader loader) dans mon thread général afin que toutes les class appelées par le bon chargeur, même celles appelées dans les class appelées dans le thread (appelle secondaire) ?
    Je ne sais pas, j'ai jamais essayé. J'ai employé une autre tactique: je delegue le chargement des classes "standard" au system class loader. Seules les classes "perso" sont chargées par mon classloader.

    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
     
    public synchronized Class loadClass(String name, boolean resolve) throws ClassNotFoundException {
     
    	Class c= findLoadedClass(name);
    	if (c != null) return c;
     
    	// Usual Java classes are loaded by the system class loader
    	if (!name.startsWith("com.appli.perso.")) {
    		c = findSystemClass(name);
    		return c;
    	}
     
    	// Application classes are loaded by our own class loader:
    	// ...
    }
    ALGORITHME (n.m.): Méthode complexe de résolution d'un problème simple.

  8. #8
    Membre éclairé
    Inscrit en
    Décembre 2005
    Messages
    251
    Détails du profil
    Informations forums :
    Inscription : Décembre 2005
    Messages : 251
    Par défaut
    salut,

    C'est ce que je fais déjà quel part. Car je ne charge que les class perso avec mon loader et pas toutes les autres class (ex JFrame,JPanel,...) sont chargées avec le charger par défaut. C'est d'ailleurs pour cela que j'ai surchargé la méthode findClass uniquement, comme cela il utilise le chargeur par défaut en priorité.
    Pour mon problème je suis un peu dans les choux. Peut être qu'il faut charger avec un ordre précis toutes mes class, ce qui n'est pas mon cas.

  9. #9
    Rédacteur
    Avatar de pseudocode
    Homme Profil pro
    Architecte système
    Inscrit en
    Décembre 2006
    Messages
    10 062
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Architecte système
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2006
    Messages : 10 062
    Par défaut
    Citation Envoyé par philippe13
    C'est ce que je fais déjà quel part. Car je ne charge que les class perso avec mon loader et pas toutes les autres class (ex JFrame,JPanel,...) sont chargées avec le charger par défaut.
    Je suppose que tu veux dire que la classe qui crée tes instances de JPanel utilise le system ClassLoader.

    Par contre, tu dois avoir une autre classe qui utilise ce JPanel et pour l'utiliser, cette classe fait un import de JPanel. Comme cette classe doit utiliser ton ClassLoader Perso, lorsqu'elle fait l'import de JPanel, elle utilise aussi le ClassLoader Perso => tu as en memoire deux definitions de la classe JPanel, une dans le System ClassLoader et une dans ton ClassLoader Perso !

    Et c'est pas de bol, car la création de l'instance et l'utilisation de l'instance n'utilisent pas la meme definition ==> Link Error

    D'ou mon exemple dans lequel mon ClassLoader Perso ne charge pas les classes "standard" (JPanel, ...) mais utilise le StandardClassLoader.
    ALGORITHME (n.m.): Méthode complexe de résolution d'un problème simple.

  10. #10
    Membre éclairé
    Inscrit en
    Décembre 2005
    Messages
    251
    Détails du profil
    Informations forums :
    Inscription : Décembre 2005
    Messages : 251
    Par défaut
    Salut,

    Je n'ai pas tout suivi dans ce que tu m'as dit
    Ce que je voulai dire : c'est que si je laisse mais fichier point class dans un dossier quelqonque et que je charge mes class.AES avec mon loadPerso et que je charge une class abstraite perso après la class fille alors il il y a cette erreur :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    Trowable java.lang.LinkageError: duplicate class definition: comrs232
    runClass3
    comrs232 étant une class mere.

    Ceci me fait croire que par défaut mon charger de class n'utilise pas ma surcharge findClass.

    Pour ton code, il me suffit de l'introduire dans mon chargeur de class en remplaçant findLaodClass par mon findClass ?

  11. #11
    Rédacteur
    Avatar de pseudocode
    Homme Profil pro
    Architecte système
    Inscrit en
    Décembre 2006
    Messages
    10 062
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Architecte système
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2006
    Messages : 10 062
    Par défaut
    Citation Envoyé par philippe13
    Salut,

    Je n'ai pas tout suivi dans ce que tu m'as dit
    Mince, c'etait pourtant clair

    Ce que je voulai dire : c'est que si je laisse mais fichier point class dans un dossier quelqonque et que je charge mes class.AES avec mon loadPerso et que je charge une class abstraite perso après la class fille alors il il y a cette erreur : duplicate class definition
    C'est ce que j'expliquais. Tu as 2 definitions de la classe. La premiere est chargée par le class loader "normal" de java, la seconde est chargée par ton class loader => ambiguité => Link error

    Comme tu le disais plus haut, essaye de déclarer ton class loader le plus tot possible (avec setContextClassLoader) , par exemple dans une classe minimaliste:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    public class Launcher {
        public static void main(String[] args) throws Exception {
            ClassLoader loader = new XXXX();
            Thread.currentThread().setContextClassLoader( loader );
            Class c = loader.loadClass("ma.vraie.appli.MainClass");
            Method m = c.getMethod("main", String[].class);
            m.invoke(null, args);
        }
    }
    NB: j'ai jamais testé cette methode, alors...
    ALGORITHME (n.m.): Méthode complexe de résolution d'un problème simple.

  12. #12
    Membre éclairé
    Inscrit en
    Décembre 2005
    Messages
    251
    Détails du profil
    Informations forums :
    Inscription : Décembre 2005
    Messages : 251
    Par défaut
    salut,

    voici ce que j'ai essayé :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    try{
                ClassLoader loader = new LoaderCrypt("C:\\Documents and Settings\\DELL2\\Bureau\\secret.key");
                Thread.currentThread().setContextClassLoader( loader );
                Class c = loader.loadClass("C:\\Documents and Settings\\DELL2\\Bureau\\AES\\Test");
                String[] arg = new String[] {};
                Method m = c.getMethod("main", arg.getClass());
                m.invoke(null, (Object) arg);
            }
            catch(Throwable e){System.out.println("main "+e);}
    et voici la réponse :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    main java.lang.reflect.InvocationTargetException
    Elle intervient après le chargement de la première class commencé à charger la première méthode.

    Je ne comprends pas très bien cette exception.

  13. #13
    Membre éclairé
    Inscrit en
    Décembre 2005
    Messages
    251
    Détails du profil
    Informations forums :
    Inscription : Décembre 2005
    Messages : 251
    Par défaut
    salut,

    c'est bon ça marche j'ai enlevé tous les fichiers point class et laissés que les fichiers .AES (ce qui sont cryptés) et ça marche!!!!!





    Je sui s très heureux et merci beaucoup encore et encore car tout seul je crois que j'aurai jeté l'eponge....

    Bonne soirée.

    PS: je prends un sirop de 12

  14. #14
    Rédacteur
    Avatar de pseudocode
    Homme Profil pro
    Architecte système
    Inscrit en
    Décembre 2006
    Messages
    10 062
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Architecte système
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2006
    Messages : 10 062
    Par défaut
    Cool. C'etait un plaisir...

    n'oublie pas le
    ALGORITHME (n.m.): Méthode complexe de résolution d'un problème simple.

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

Discussions similaires

  1. [JDOM] java.lang.NoClassDefFoundError : NamespaceContext
    Par pierreonxbox dans le forum Format d'échange (XML, JSON...)
    Réponses: 3
    Dernier message: 11/04/2006, 09h43
  2. [DisplayTag] java.lang.NoClassDefFoundError: org/apache/commons/lang/UnhandledException
    Par MAJIK_ENIS dans le forum Taglibs
    Réponses: 18
    Dernier message: 06/04/2006, 10h18
  3. [Plugin][Hibernate Tools] java.lang.NoClassDefFoundError
    Par notrustinyou dans le forum Eclipse Java
    Réponses: 2
    Dernier message: 28/11/2005, 17h17
  4. [ eclipse3 ] [ Deb. ] java.lang.NoClassDefFoundError:
    Par Marc_3 dans le forum Eclipse Java
    Réponses: 2
    Dernier message: 19/10/2005, 12h26
  5. [Struts] java.lang.NoClassDefFoundError
    Par Zephoria dans le forum Struts 1
    Réponses: 2
    Dernier message: 08/02/2005, 10h51

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