2011-01-28 2 views
35

Est-ce que JRebel utilise Javassist ou une sorte de manipulation bytecode? Je demande cela par pur intérêt, je n'ai pas vraiment besoin de savoir :)Comment fonctionne JRebel?

Répondre

43

JRebel utilise la réécriture de classe (ASM et Javassist) et l'intégration JVM pour la version des classes individuelles. De plus, il s'intègre aux serveurs d'applications pour rediriger les recherches de classes/ressources et de serveurs Web vers l'espace de travail. Et il s'intègre également avec la plupart des serveurs d'applications et des frameworks pour propager les modifications de la configuration (métadonnées ou fichiers). C'est le manque. Le long de cela prend 10 ingénieurs de classe mondiale pour développer et soutenir et est notre secret commercial :)

+2

@Jevgeni Kabanov: Ne JRebel gérer le rechargement des classes finales? – Dexter

+1

@Dexter il fait –

4

C'est le raisonnement le plus proche que j'ai lu sur comment JRebel works par Simon, ZT Technical Evangelist.

le contenu ici Coller:


instruments JRebel l'application et les classes JVM pour créer une couche d'indirection. Dans le cas où une classe d'application est chargée, tous les corps de méthode auront une redirection utilisant le service de redirection d'exécution, comme illustré dans la Figure 2. Ce service gère et charge les versions de classe et de méthode en utilisant des classes internes anonymes créées pour chaque version rechargée. Regardons un exemple. Nous allons créer une nouvelle classe C avec deux méthodes:

public class C extends X { 
int y = 5; 
int method1(int x) { 
    return x + y; 
} 
void method2(String s) { 
    System.out.println(s); 
} 
} 

Lorsque la classe C est chargé pour la première fois, les instruments JRebel la classe. La signature de cette classe sera la même, mais les corps de la méthode sont en train d'être redirigés. La classe chargée va maintenant quelque chose comme ceci:

public class C extends X { 
int y = 5; 
int method1(int x) { 
    Object[] o = new Object[1]; 
    o[0] = x; 
    return Runtime.redirect(this, o, "C", "method1", "(I)I"); 
} 
void method2(String s) { 
    Object[] o = new Object[1]; 
    o[0] = s; 
    return Runtime.redirect(this, o, "C", "method2", "(Ljava/lang/String;)V"); 
} 
} 

Pour les appels de redirection, nous passant l'objet d'appel, les paramètres à la méthode qui a été appelé, le nom de notre classe, notre nom de la méthode et les types de les paramètres et le retour. JRebel charge également une classe avec les implémentations à une version spécifique, d'abord la version 0. Voyons voir ce qui ressemble à:

public abstract class C0 { 
public static int method1(C c, int x) { 
    int tmp1 = Runtime.getFieldValue(c, "C", "y", "I"); 
    return x + tmp1; 
} 
public static void method2(C c, String s) { 
    PrintStream tmp1 = 
    Runtime.getFieldValue(
     null, "java/lang/System", "out", "Ljava/io/PrintStream;"); 
    Object[] o = new Object[1]; 
    o[0] = s; 
    Runtime.redirect(tmp1, o, "java/io/PrintStream;", "println","(Ljava/lang/String;)V"); 
} 
} 

Disons que maintenant que l'utilisateur modifie leur classe C en ajoutant une nouvelle méthode z() et l'invocation il de la méthode1. Classe C ressemble maintenant à ceci:

public class C { 
int y = 5; 
int z() { 
    return 10; 
} 
int method1(int x) { 
    return x + y + z(); 
} 
... 
} 

La prochaine fois que les runtimes utilise cette classe, il JRebel détecte une version plus récente qui a été compilé et sur le système de fichiers, il charge la nouvelle version, C1. Cette version a la méthode supplémentaire z et l'implémentation mise à jour pour la méthode1.

public class C1 { 
public static int z(C c) { 
    return 10; 
} 
public static int method1(C c, int x) { 
    int tmp1 = Runtime.getFieldValue(c, "C", "y", "I"); 
    int tmp2 = Runtime.redirect(c, null, "C", "z", "(V)I"); 
    return x + tmp1 + tmp2; 
} 
... 
} 

L'appel Runtime.redirect sera toujours mis en déroute à la dernière version de la classe C, afin d'appeler nouveau C(). Method1 (10) retournerait 15 avant le changement de code et 25 par la suite. Cette implémentation manque beaucoup de détails et d'optimisations, mais vous avez l'idée.

Source: http://zeroturnaround.com/rebellabs/why-hotswap-wasnt-good-enough-in-2001-and-still-isnt-today/

Questions connexes