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 :

Redéfinir une classe


Sujet :

Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre chevronné
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    361
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2006
    Messages : 361
    Par défaut Redéfinir une classe
    Bonjour,

    Dans mon programme j'ai besoin de faire quelques modifications sur des classes et j'utilise pour cela ASM. J'ai toutefois quelques problèmes pour appliquer ces modifications ...

    En gros, j'ai une classe abstraite Message.
    Celle-ci va être étendue par d'autres classes que je ne connais pas avant l'exécution.
    Je dois donc récupérer la liste des classes. Pour me facilité la tâche, elles doivent être dans des packages que je connais.

    J'arrive donc à ma question. Ces classes vont être modifiées via ASM, mais comment faire pour appliquer ces modifications ?

    Dans le guide ils disent qu'il faut utiliser la classe ClassFileTransformer du package java.lang.instrument.

    La doc du package indique qu'il faut créer un agent. J'ai bien compris comment le créer, mais je ne vois pas comment mon agent va connaître les classes à modifier, alors que celle-ci ne sont pas encore chargées ? En effet il me semble qu'une classe est chargée via le ClassLoader quand on essaie de l'instancier. Hors dans mon cas les classes ne seront pas instancier vu que l'agent est exécuter avant la méthode main du programme...

    Bref je ne vois pas trop comment m'y prendre ...
    Si quelqu'un à une idée là dessus, ça m'intéresse.

    Merci.

    P.S: j'utilise Java 6 (et java 7 dès qu'elle sera un peu plus avancée)

    Edit: j'aurais peut être du mettre mon topic dans API ...

  2. #2
    Membre chevronné
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    361
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2006
    Messages : 361
    Par défaut
    Je viens de voir que dans java 6 il est possible de déployer un agent même si l'application a déjà démarrée.
    Ca permet par exemple d'utiliser la JConsole même si on a pas utilisé l'option "-Dcom.sun.management.jmxremote" lors du lancement du programme.

    Est-il possible de redéfinir une classe même si celle-ci a déjà été utilisée ?

  3. #3
    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
    Par défaut
    Hello,

    Citation Envoyé par nicØB
    Ces classes vont être modifiées via ASM, mais comment faire pour appliquer ces modifications ?
    que je comprenne bien: ASM c'est quand même pas pour "Assembleur" ? Parce que là, en java, on est vraiment vraiment loin de l'assembleur...

    Sinon, plus globalement, pour charger n'importe quelle classe qui existe dans le classpath et qui n'a pas encore forcément été chargée, il suffit d'appeler:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Class c = Class.forName("mypack.MyClass");


    qui renvoie une instance de classe Class... ou lève des exceptions si un problème est rencontré.

    Ensuite, à partir de ça, tu instancie avec:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Object o = c.newInstance();



  4. #4
    Membre expérimenté
    Avatar de mathk
    Inscrit en
    Décembre 2003
    Messages
    211
    Détails du profil
    Informations forums :
    Inscription : Décembre 2003
    Messages : 211
    Par défaut
    Citation Envoyé par Pill_S
    que je comprenne bien: ASM c'est quand même pas pour "Assembleur" ? [SIZE=1]Parce que là, en java, on est vraiment vraiment loin de l'assembleur...

    No! ASM c'est une librairies pour Java ca m'a pris 5 sec a chercher sur le web

  5. #5
    Membre chevronné
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    361
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2006
    Messages : 361
    Par défaut
    Salut Pill_S et merci pour ta réponse.

    En fait ASM de objectweb pour modifier ou créer du bytecode.

    Je crée déjà dynamiquement de nouvelles classes, donc pas de problème pour les définir et les utiliser.
    Là où il y a un problème, c'est pour modifier des classes existantes. Si on modifie juste le code d'une fonction, ça va. Mais si on ajoute une nouvelle fonction, ou qu'on ajoute/modifie des champs, là c'est autre chose.


    Voila ce qu'il dise à propos de l'utilisation des classes modifiées, dans le guide d'ASM:
    class transformations done inside a ClassLoader can only transform the classes loaded by this class loader. If you want to transform all classes you will have to put your transformation inside a ClassFileTransformer, as defined in the java.lang.instrument package (see the documentation of this package for more details):
    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
    public static void premain(String agentArgs, Instrumentation inst)
    {
    	inst.addTransformer(new ClassFileTransformer()
    	{
    		public byte[] transform(ClassLoader l, String name, Class c,
    				ProtectionDomain d, byte[] b)
    				throws IllegalClassFormatException
    		{
    			ClassReader cr = new ClassReader(b);
    			ClassWriter cw = new ClassWriter(cr, 0);
    			ClassVisitor cv = new ChangeVersionAdapter(cw);
    			cr.accept(cv, 0);
    			return cw.toByteArray();
    		}
    	});
    }
    Et donc en lisant la doc du package java.lang.instrument je suis tombé sur ce que j'ai dit plus haut.


    Pour les gens que ça intéresse, voici un lien qui explique comment ajouter dynamiquement du code Java à une application (Java) qui est déjà lancée, à l'aide de java 6.
    Dans mon cas, ça ne me sers à pas à grand chose ...


    Bon, je continue mes recherches.
    Je posterai ici ce que je trouve.

  6. #6
    Membre chevronné
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    361
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2006
    Messages : 361
    Par défaut
    J'ai finalement trouvé.

    Il faut créer un agent: une classe avec une méthode "public static void premain(String args, Instrumentation inst)", qui est appelée avant le main de l'application.

    Dans celle-ci, il faut ajouter un ClassFileTransformer au paramètre inst.
    Toutes les classes de l'application passeront par la méthode transform de ce ClassFileTransformer lorsqu'elles seront chargées. Il suffit donc de modifier le bytecode à ce moment là.


    Enfin, il faut faire un .jar avec cet agent, puis appeler le programme avec cette option (pour la JVM): -javaagent:monAgent.jar


    Exemple ici.

    Bon week end.

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

Discussions similaires

  1. Redéfinir une méthode static dans une classe dérivée
    Par michelp3 dans le forum Général Java
    Réponses: 5
    Dernier message: 06/05/2015, 22h28
  2. Redéfinir un constructeur dans une classe interne anonyme
    Par pigpen dans le forum Débuter avec Java
    Réponses: 3
    Dernier message: 31/10/2011, 13h36
  3. Réponses: 6
    Dernier message: 31/07/2009, 09h56
  4. Variable d'une Classe Ancêtre
    Par Génie dans le forum Langage
    Réponses: 3
    Dernier message: 18/09/2002, 19h24
  5. Sortir un typedef d'une classe
    Par Theophil dans le forum C++Builder
    Réponses: 13
    Dernier message: 03/07/2002, 17h21

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