Saltar al contenido

¿Cómo reemplazar clases en una aplicación en ejecución en Java?

Posterior a de esta larga compilación de datos dimos con la solución esta contrariedad que presentan muchos de nuestros usuarios. Te regalamos la respuesta y nuestro objetivo es servirte de mucha apoyo.

Solución:

Aquí hay una prueba de trabajo. Cada 5 segundos Test.main() vuelve a cargar test.Test1.class desde el sistema de archivos y llama a Test1.hello()

package test;

public class Test1 
    public void hello() 
        System.out.println("Hello !");
    


public class Test 

    static class TestClassLoader extends ClassLoader 
        @Override
        public Class loadClass(String name) throws ClassNotFoundException 
            if (name.equals("test.Test1")) 
                try 
                    InputStream is = Test.class.getClassLoader().getResourceAsStream("test/Test1.class");
                    byte[] buf = new byte[10000];
                    int len = is.read(buf);
                    return defineClass(name, buf, 0, len);
                 catch (IOException e) 
                    throw new ClassNotFoundException("", e);
                
            
            return getParent().loadClass(name);
        
    

    public static void main(String[] args) throws Exception 
        for (;;) 
            Class cls = new TestClassLoader().loadClass("test.Test1");
            Object obj = cls.newInstance();
            cls.getMethod("hello").invoke(obj);
            Thread.sleep(5000);
        
    

Ejecutarlo. Luego cambie y vuelva a compilar Test1

System.out.println("Hello !!!");

mientras se ejecuta la prueba. Verá que la salida Test1.hello cambió

...
Hello !
Hello !
Hello !!!
Hello !!!

Así es como, por ejemplo, Tomcat recarga aplicaciones web. Tiene un ClassLoader separado para cada aplicación web y carga una nueva versión en un ClassLoader nuevo. El anterior se procesa como cualquier objeto Java, así como las clases anteriores.

Tenga en cuenta que cargamos Test1 con TestClassLoader e invocamos su primer método con reflexión. Pero todas las dependencias de Test1 se cargarán implícitamente con el cargador de clases Test1, es decir, JVM cargará toda la aplicación Test1 en TestClassLoader.

Si piensas que ha resultado de ayuda este post, sería de mucha ayuda si lo compartes con el resto juniors así contrubuyes a dar difusión a esta información.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *