java - plug - Cambiar un método en tiempo de ejecución a través de un mecanismo de intercambio en caliente
hot plug hdd (7)
Supongamos que tenemos un programa trivial de Java que consiste en una sola clase:
public class HelloWorld {
private static void replacable(int i) {
System.out.println("Today is a nice day with a number " + i);
}
public static void main(String[] args) throws Exception {
for(int i = 0; i < 100000; ++i) {
replacable(i);
Thread.sleep(500);
}
}
Después de compilarse y ejecutarse, la salida será esta:
Hoy es un buen día con un número 0
Hoy es un buen día con un número 1
Hoy es un buen día con un número 2
Hoy es un buen día con un número 3
...
Mi pregunta: ¿existe (o hay en el horizonte) alguna forma de intercambiar el método replacable
en el tiempo de ejecución? ¿Algo como escribir otra versión de HelloWorld
con una nueva versión de replacable
, compilando y luego la versión anterior en una JVM ya en ejecución?
Entonces, si escribo la nueva versión de esta manera:
private static void replacable(int i) {
System.out.println("Today is an even nicer day with a number " + i);
}
¿Hay algo similar al intercambio de código caliente de Erlang en el que puedo hacer esto?
- ejecutar el programa original
- escribir versión modificada
- usando un programa de línea de comando, conéctese a ejecutar JVM y reemplace el método existente
para que, durante el tiempo de ejecución, esto suceda:
Hoy es un buen día con un número 15000
Hoy es un buen día con un número 15001
Hoy es un día aún más agradable con un número 15002
Hoy es un día aún más agradable con un número 15003
...
Supongamos que el programa anterior es independiente, se ejecuta en un entorno Java SE estándar, no hay nada más en classpath, por lo que es casi un programa Hello world style.
Nota: Sé que cglib tecnologías como la manipulación de cglib ( cglib ), aspectJ , jRebel , JMX , hotswapping de métodos en Java EE, etc., pero no son en lo que estoy pensando. Piensa en Erlang.
¿Qué hay de OSGi? El intercambio en caliente está "incorporado" a la especificación, creo que esta sería una posible solución también.
He usado esta tarea de hotswap en muchos proyectos. La aplicación Java de destino se puede iniciar a través de Ant, Eclipse, un símbolo del sistema o cualquier otro medio, siempre que se lance en modo de depuración con el puerto apropiado abierto. La página vinculada proporciona instrucciones sobre cómo hacer esto a través de Ant.
Cualquier número de clases puede ser enmascarado siempre que los cambios no sean estructurales. Los cambios en el cuerpo del método generalmente se intercambian con facilidad. El código puede ser enmascarado ejecutando un script ant a través de un shell o Eclipse.
En el trabajo, utilizo un script que cambia el código de hotswaps automáticamente al comparar las marcas de tiempo en los archivos de clase. Esto es similar a la muestra en la página del proyecto que muestra un ejemplo simple que solo hotswaps cambió las clases.
Nota adicional: Esto utiliza el JPDA .
Podría usar el patrón de diseño de Estrategia, de modo que tenga un objeto para manipular en lugar de un método, y un protocolo para comunicarse con el programa para indicarle que use un nombre de clase dado como la clase del objeto de Estrategia.
Puede hacerlo a través de la interfaz JPDA (Java Platform Debugger Architecture): http://download.oracle.com/javase/1.4.2/docs/guide/jpda/enhancements.html#hotswap
No es automático como el caso de Erlang: la JVM no supervisa la ruta de la clase para cambios en los archivos de la clase y luego vuelve a cargarlos y volver a vincularlos si se modifican, por razones bastante obvias (Java se diseñó para la implementación web; no se desea sondear una http URL para cambios).
Puede utilizar la máquina virtual de HotSpot de código abierto o el JRebel comercial IDE de JRebel para alcanzar fácilmente su objetivo (consulte la tabla de comparación here ).
Puedes hacerlo a través de cargadores de clases. Por ejemplo, si está familiarizado con contenedores Servlet como tomcat que vuelven a cargar páginas a medida que las modifica en el desarrollo. Aquí hay una gran explicación para crear código dinámico en java . No solo explica la carga sino también la compilación de la fuente sobre la marcha. Debe poder aplicar los conceptos cubiertos a cualquier estrategia de recarga de código que desee utilizar.
Una publicación un poco antigua, pero con suerte alguien lo encontrará útil:
Descubrí que el relativamente nuevo agente de Hotswap está bien documentado y tiene muchas funciones (y, lo mejor de todo, de código abierto ).