Pregunta

Tengo algo como esto:

public static final String path;
static {
    path = loadProperties("config.conf").getProperty("path");
}

public static void main(String... args) {

    // ... do stuff (starting threads that reads the final path variable)

    // someone want's to update the path (in the config.conf file)
    restart(); // ???
}

Quiero reiniciar la JVM llamando a la estática inicializador de nuevo, y luego main(...)!

¿Se puede hacer?

¿Fue útil?

Solución

Se puede iniciar la aplicación usando un cargador de clase personalizada, esto le permitirá cargar y descargar sus variables estáticas.

Sin embargo, en el fondo es un diseño muy malo a tener que hacer esto. Me gusta hacer campos final, pero que no debería hacerlos final si desea cambiar ellos.

Otros consejos

Si su objetivo es simplemente para recargar algunos archivos de configuración, por qué no implementar un monitor de modificación del archivo?

Aquí hay un buen tutorial sobre este tema:

http://download.oracle.com/javase/tutorial/ esencial / io / notification.html

Creo que lo que estamos proponiendo (reiniciar su aplicación automáticamente) sería un poco más complicado que simplemente mirando para actualizaciones de archivos.

Peter Lawrey respuesta, pero poner un ejemplo completo de utilizar por cualquiera!

no voy a usar esto en el código de producción ... hay otras maneras de hacerlo!

public class Test {

    public static void main(String args[]) throws Exception {
        start();
        Thread.sleep(123);
        start();
    }

    private static void start() throws Exception {

        ClassLoader cl = new ClassLoader(null) {
            protected java.lang.Class<?> findClass(String name) 
            throws ClassNotFoundException {
                try{
                    String c = name.replace('.', File.separatorChar) +".class";
                    URL u = ClassLoader.getSystemResource(c);
                    String classPath = ((String) u.getFile()).substring(1);
                    File f = new File(classPath);

                    FileInputStream fis = new FileInputStream(f);
                    DataInputStream dis = new DataInputStream(fis);

                    byte buff[] = new byte[(int) f.length()];
                    dis.readFully(buff);
                    dis.close();

                    return defineClass(name, buff, 0, buff.length, null);

                } catch(Exception e){
                    throw new ClassNotFoundException(e.getMessage(), e);
                }
            }
        };

        Class<?> t = cl.loadClass("Test$Restartable");
        Object[] args = new Object[] { new String[0] };
        t.getMethod("main", new String[0].getClass()).invoke(null, args);
    }

    public static class Restartable {

        private static final long argument = System.currentTimeMillis();

        public static void main(String args[]) throws Exception {
            System.out.println(argument);
        }
    }
}

Un enfoque más sencillo es simplemente no para utilizar el inicializador estático para esto. ¿Por qué no simplemente hacer path no final y cargarlo en main?

¿qué hay de esta estructura

public static void main(String... args) {

    boolean restart = true;
    while (restart )
    {
        retart = runApplication();
    }

}

Si alguna vez detecta la necesidad de que reiniciar la aplicación, tener runApplication return true. Si es el momento de retorno falsa salida;

Si usted tiene una interfaz de usuario o un demonio para que pueda controlar la salida estándar, se puede hacer un envoltorio en el exterior que se inicia el programa.

Si el programa sobre las salidas de salida "REINICIO" puede volver a iniciar de nuevo el programa de esta envoltura. Si no es así, simplemente extremos.

O si desea que la forma pura de Java, se puede ir con una solución con cargadores de clases como Peter Lawrey menciona en su puesto. Antes de ir por este camino que realmente debería reconsiderar su diseño (si es su código) y hacer que su código capaz de limpiar a sí mismo.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top