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

Langage Java Discussion :

Forcer la JVM à recharger une classe.


Sujet :

Langage Java

  1. #1
    Futur Membre du Club
    Inscrit en
    Novembre 2008
    Messages
    14
    Détails du profil
    Informations forums :
    Inscription : Novembre 2008
    Messages : 14
    Points : 9
    Points
    9
    Par défaut Forcer la JVM à recharger une classe.
    Bonjour,

    voici mon problème : je dois développer un logiciel dont une partie fait appel à de la JNI pour appeler la dll d'un programme écrit en C. Mon problème est que je dois pouvoir automatiquement réinitialiser ce programme en C (le fermer puis le relancer). Je me dis donc qu'une solution consisterait à décharger de la mémoire la classe java faisant un appel static aux dll puis à la recharger.

    J'ai vu dans la FAQ l'article pour recharger dynamiquement une classe : http://java.developpez.com/faq/java/...iquementClasse
    Cependant, je n'obtiens pas l'effet escompté. Je ne trouve pas dans les traces d'exécution le signe que mes dll ont été rechargés. Y a-t-il un moyen de forcer la main à la JVM pour qu'elle "décharge" de sa mémoire une classe ?
    Fais-je fausse route : le rechargement de ma classe java relancera-t-il de zéro mon programme C ?

    Merci d'avance

  2. #2
    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
    je suis loin d'être un expert jni, mais je ne comprend pas vraiment pourquoi tu dois recharger la dll? a-t-elle changée entre 2 exécutions?

  3. #3
    Futur Membre du Club
    Inscrit en
    Novembre 2008
    Messages
    14
    Détails du profil
    Informations forums :
    Inscription : Novembre 2008
    Messages : 14
    Points : 9
    Points
    9
    Par défaut
    En fait, cette dll va lire un fichier de configuration quand elle se lance. C'est ce fichier de configuration que j'ai changé entre deux exécution (ce qui finalement revient à avoir changé la dll). C'est pourquoi j'aimerais pouvoir forcer le relancement de cette dll (pour l'obliger à aller lire le fichier de configuration).

    A priori, l'interface avec cette dll est figée, je ne peux donc pas rajouter une fonction qui me permettrait de lui demander (gentiment) d'aller relire le fichier de conf.

  4. #4
    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
    Hum ok, a priori je vois pas vraiment de solution simple.

    Y'aurait moyen de bidouiller, mais je pense pas qu'aucune bidouille ne soit vraiment intéressante.

    1) copier et renommer la dll à chaque fois, puis appeler jni sur la dll avec le nouveau nom (si 2 dll ont des noms différents, je suis presque sûr qu'elle sera rechargée)
    2) faire un wrapper en C autour de cette dll qui permette d'étendre l'interface (risque de compatibilité si mise à jour de la dll wrappée)

    A priori je ne vois que ça, donc en fait rien de vraiment intéressant...

  5. #5
    Futur Membre du Club
    Inscrit en
    Novembre 2008
    Messages
    14
    Détails du profil
    Informations forums :
    Inscription : Novembre 2008
    Messages : 14
    Points : 9
    Points
    9
    Par défaut
    Merci pour ta réponse, je vais quand même essayer de voir si j'arrive à mon but en renommant la dll.

  6. #6
    Modérateur
    Avatar de OButterlin
    Homme Profil pro
    Inscrit en
    Novembre 2006
    Messages
    7 313
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 7 313
    Points : 9 529
    Points
    9 529
    Billets dans le blog
    1
    Par défaut
    Pourquoi ne pas faire une méthode d'initialisation dans ta dll.
    Si le problème est lié à un fichier de paramétrage, il suffirait de refaire le traitement d'initialisation, je ne vois pas trop l'intérêt de recharger la dll puisque (d'après ce que j'ai compris) les méthodes ne changent pas, uniquement des valeurs de références ou autres éléments connexes...

    A+

  7. #7
    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
    Citation Envoyé par OButterlin Voir le message
    Pourquoi ne pas faire une méthode d'initialisation dans ta dll.
    Apparement, il reçoit la dll sous forme binaire, donc pas de modifs possibles à priori.

  8. #8
    Rédacteur

    Avatar de millie
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    7 015
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 7 015
    Points : 9 818
    Points
    9 818
    Par défaut
    Tu as utilisé quelle méthode de la FAQ ?

    Celle où la classe est dans le CLASSPATH ou la méthode où la classe n'est pas dans le CLASSPATH.

    Tu ne t'es pas arrêté sur le : Class c = Class.forName("com.developpez.MaClasse");
    ?

  9. #9
    Modérateur
    Avatar de OButterlin
    Homme Profil pro
    Inscrit en
    Novembre 2006
    Messages
    7 313
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 7 313
    Points : 9 529
    Points
    9 529
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Pill_S Voir le message
    Apparement, il reçoit la dll sous forme binaire, donc pas de modifs possibles à priori.
    Ouuuups Désolé, j'avais zappé la dernière phrase...
    Ignore donc ma stupide intervention...

  10. #10
    Futur Membre du Club
    Inscrit en
    Novembre 2008
    Messages
    14
    Détails du profil
    Informations forums :
    Inscription : Novembre 2008
    Messages : 14
    Points : 9
    Points
    9
    Par défaut
    Citation Envoyé par OButterlin
    Pourquoi ne pas faire une méthode d'initialisation dans ta dll.
    Citation Envoyé par Pill_S Voir le message
    Apparement, il reçoit la dll sous forme binaire, donc pas de modifs possibles à priori.
    En effet, je reçois bien la dll sous forme binaire. Je suis tout à fait d'accord sur le fait que si je pouvais retoucher à l'initialisation, je pourrais forcer la relecture du fichier de configuration, ce qui serait bien plus élégant comme solution que ce bricolage.

    Citation Envoyé par millie
    Tu as utilisé quelle méthode de la FAQ ?

    Celle où la classe est dans le CLASSPATH ou la méthode où la classe n'est pas dans le CLASSPATH.

    Tu ne t'es pas arrêté sur le : Class c = Class.forName("com.developpez.MaClasse");
    ?
    J'ai essayé cette première méthode mais comme la classe faisant appel à la JNI est dans un jar dans le CLASSPATH de mon projet, je me doutais que ça ne marcherais pas.

    En recopiant le code de la classe MonLoadeur de la FAQ, j'avais un code qui compilait et s'exécutait sans erreur mais la dll n'était pas rechargée (les traces caractéristiques n'apparaissaient pas dans la console).

    Y aurait-il moyen de faire en sorte de demander à la JVM de décharger une classe de sa mémoire ? Si j'ai bien compris, par défaut, une classe reste chargée (même si je n'ai plus aucune poignée sur un objet du type de la classe) tant que mon programme tourne ?

    Merci pour vos réponses et bonne journée

  11. #11
    Rédacteur

    Avatar de millie
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    7 015
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 7 015
    Points : 9 818
    Points
    9 818
    Par défaut
    Citation Envoyé par Sierra3193 Voir le message
    J'ai essayé cette première méthode mais comme la classe faisant appel à la JNI est dans un jar dans le CLASSPATH de mon projet, je me doutais que ça ne marcherais pas.
    Salut,

    Si tu as fait : Class c = Class.forName("com.developpez.MaClasse"); , c'est normal que ça ne marche pas, c'est écrit dans la Q/A de la FAQ.

    Ce ClassLoader cache l'information et ne rechargera pas la classe lors d'un nouvel appel a forName, et ce même si le fichier ".class" a changé depuis le dernier chargement.
    Il faut faire la méthode : 2 - La classe est présente dans le CLASSPATH

  12. #12
    Futur Membre du Club
    Inscrit en
    Novembre 2008
    Messages
    14
    Détails du profil
    Informations forums :
    Inscription : Novembre 2008
    Messages : 14
    Points : 9
    Points
    9
    Par défaut
    Citation Envoyé par millie Voir le message
    Il faut faire la méthode : 2 - La classe est présente dans le CLASSPATH
    Désolé, je n'ai pas été assez clair. J'ai également essayé la deuxième méthode, quand la classe est dans le CLASSPATH, en créant sa propre classe qui étend ClassLoader (j'ai recopié le code de la FAQ). C'est dans ce cas là que je disais que le code compilait et s'exécutait mais que je ne retrouvais pas les traces d'initialisation de la dll.

  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
    Hi,

    Il est peut être possible de forcer le rechargement de la classe et de la dll en jouant avec les classloaders. Malheureusement, ce sont des manipulations bas niveaux assez dangereuses, avec plein de runtimeexceptions succeptibles d'arriver dans certains cas

    En gros:
    - charger cette classe ainsi que toutes celles à recharger à partir d'un classloader différent. Ne pas la(es) charger à partir du classloader standard (System classloader)

    Lorsque l'on veut recharger la classe:
    - mettre toutes les références sur la classe à null. Mettre toutes les références sur le classloader à null
    - invoquer System.gc() jusqu'à ce que le classloader soit recyclé

    Ensuite, tu pourras recrééer un nouveau classloader et recommencer à charger des classes.

    Recherche "java unload class" sur google, il y a quelques articles en anglais qui peuvent t'intéresser.

Discussions similaires

  1. Forcer la taille de x image contenu dans une class
    Par mael94420 dans le forum jQuery
    Réponses: 2
    Dernier message: 12/06/2009, 06h55
  2. Recharger une classe en cours d'exécution
    Par frites.saucisse dans le forum Général Python
    Réponses: 9
    Dernier message: 23/08/2008, 09h57
  3. forcer l'utilisation d'une classe
    Par TheBlackReverand dans le forum C#
    Réponses: 10
    Dernier message: 11/02/2008, 15h47
  4. Réponses: 3
    Dernier message: 15/01/2008, 17h10
  5. recharger dynamiquement une classe
    Par orelero dans le forum Général Java
    Réponses: 4
    Dernier message: 02/10/2006, 13h09

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