2011-01-28 8 views
35

¿Utiliza JRebel Javassist o algún tipo de manipulación de bytecode? Estoy pidiendo esto por puro interés, en realidad no "necesito" saber :)¿Cómo funciona JRebel?

Respuesta

43

JRebel utiliza la reescritura de clase (tanto ASM como Javassist) y la integración de JVM para versionar clases individuales. Además, se integra con los servidores de aplicaciones para redirigir las búsquedas de clases/recursos y servidores web al espacio de trabajo. Y también se integra con la mayoría de los servidores de aplicaciones y marcos para propagar los cambios a la configuración (metadatos o archivos). Eso es todo. El largo de que se necesitan 10 ingenieros de clase mundial para desarrollar y apoyar y es nuestro secreto comercial :)

+2

@Jevgeni Kabanov: Lo que JRebel gestionar la recarga de clases finales? – Dexter

+1

@Dexter lo hace –

4

Este es el razonamiento más cercano que he leído sobre cómo JRebel works de Simon, ZT Technical Evangelist.

pegar el contenido aquí:


instrumentos JRebel la aplicación y clases de JVM para crear una capa de direccionamiento indirecto. En el caso de que se cargue una clase de aplicación, todos los cuerpos de método tendrán una redirección utilizando el servicio de redirección de tiempo de ejecución, como se muestra en la Figura 2. Este servicio administra y carga las versiones de clase y método utilizando clases internas anónimas creadas para cada versión que se recarga. Veamos un ejemplo. Vamos a crear una nueva clase C con dos métodos:

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

Cuando Clase C se carga por primera vez, los instrumentos JRebel la clase. La firma de esta clase será la misma, pero los cuerpos del método ahora están siendo redirigidos. La clase cargada ahora se verá algo como esto:

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"); 
} 
} 

Para las llamadas de redirección, que pasa en el objeto de llamada, los parámetros al método que se ha llamado, el nombre de nuestra clase, nuestro nombre de método y los tipos de los parámetros y retorno. JRebel también carga una clase con las implementaciones a una versión específica, en un principio la versión 0. Vamos a ver lo que parece:

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"); 
} 
} 

Vamos ahora dicen que el usuario cambia su clase C mediante la adición de un nuevo método z() e invocando desde el método1. Clase C ahora se ve así:

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

La próxima vez que los tiempos de ejecución utiliza esta clase, JRebel detecta que hay una versión más nueva que ha sido compilado y en el sistema de archivos, por lo que carga la nueva versión, C1. Esta versión tiene el método adicional z y la implementación actualizada para method1.

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; 
} 
... 
} 

La llamada Runtime.redirect siempre serán enviados a la última versión de la clase C, así que llamar nuevo C(). Metodo1 (10) devolvería 15 antes del cambio de código y 25 después. Esta implementación pierde muchos detalles y optimizaciones, pero se entiende la idea.

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