2017-03-22 6 views
1

Je travaille sur un projet qui nécessite l'instrumentation de classes. J'utilise javassist parce que c'est très pratique pour faire de l'instrumentation dans mon cas.javassist: renommer les classes et les types de champs

Je suis face à un problème qui peut être décrit en utilisant suivant extrait de code:

Classe Suppose 1:

public class Class1 { 
    Class2 class2; 
} 

et de classe 2:

public class Class2 { 
    //Code 
} 

Et une fonction obtenir CtClass es à partir des classes définies et faire une transformation de code.

public void testFunction() throws NotFoundException { 
     ClassPool classPlool; 
     classPlool = ClassPool.getDefault(); 
     CtClass ctCls1 = classPlool.getAndRename("Class1", "Class1_V1"); 
     // instrument and load ctCls1 etc. 
     CtClass ctCls2 = classPlool.getAndRename("Class2", "Class2_V1"); 
     // instrument and load ctCls1 etc. 
    } 

Comme, je suis renommant les cours, de sorte que le champ Class2 class2 dans Class1 est de type class Class2, mais cette classe est renommé Class2_V1. Je veux renommer le type de champ également de LClass2 à LClass2_V1.

Le ctCls1 est: [email protected][changed public class Class1_V1 fields=Class1_V1.class2:LClass2;, [email protected][public Class1_V1()V], methods=]

PS: J'ai charger deux versions de classes avec des instruments différents, il est donc la meilleure façon dans mon cas. En outre, j'ai recherché le problème, mais il n'y a aucune solution pour l'adresser, comme this link décrit pour renommer les champs, mais pas le type.

+0

S'il vous plaît noter que je joins toujours « _v1 » ou « _V2 '. Donc, cela suffira si vous m'aidez à renommer 'LClass1_V1' ou 'LClass1_V2'. – Aadarsh

+0

Pouvez-vous supprimer complètement le champ, puis ajouter un nouveau champ avec le nouveau nom et le nouveau type? – Nicholas

+0

Je peux, mais il n'y a aucune différence en supprimant puis en ajoutant et en utilisant 'setType()' – Aadarsh

Répondre

1

Selon Javassistdocumentation:

Une nouvelle classe peut être définie comme une copie d'une classe existante. Le programme fait en dessous:

ClassPool pool = ClassPool.getDefault(); 
CtClass cc = pool.get("Point"); 
cc.setName("Pair"); 

Ce programme obtient d'abord l'objet CtClass Point de classe.

Ensuite, il appelle setName() pour donner un nouveau nom Pair à cet objet CtClass. Après cet appel, toutes les occurrences du nom de classe dans la définition de classe représentée par cet objet CtClass sont modifiées de Point à Pair. L'autre partie de la définition de classe ne change pas.

EDIT: Pour renommer un type de champ dans une classe, vous pouvez naviguer dans la classe et l'obtenir par le type JavassistCtField

ClassPool pool = ClassPool.getDefault(); 
CtClass cc = pool.get("Class1"); 
CtField cf = cc.getField("class2NameIntoClass1"); 
CtClass cc2 = cf.getType(); 
cc2.setName("Class2NewName"); 
+0

Je renomme le 'class2' mais' class1' a un champ de type 'class2', la méthode, vous ne pouvez pas faire référence renommer le type dans 'class1'. – Aadarsh