Domanda

ho qualcosa di simile a questo:

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(); // ???
}

Voglio reinizializzare JVM chiamando la statica inizializzatore di nuovo, e poi main(...)!

Può essere fatto?

È stato utile?

Soluzione

È possibile avviare l'applicazione utilizzando una classe personalizzata caricatore, questo vi permetterà di caricare e scaricare le variabili statiche.

Tuttavia, in pratica la sua una pessima progettazione alla necessità di fare questo. Mi piace fare campi di finale, ma non si dovrebbe fare li finale, se si desidera cambiare loro.

Altri suggerimenti

Se il vostro obiettivo è semplicemente quello di caricare alcuni file di configurazione, perché non implementare un monitor di modifica del file?

Ecco un buon tutorial su questo argomento:

http://download.oracle.com/javase/tutorial/ essenziale / IO / notification.html

Credo che ciò che si sta proponendo (riavviare l'applicazione automaticamente) sarebbe un ingombrante po 'più di un semplice guardare per gli aggiornamenti dei file.

Sono accettare Peter Lawrey risposta, ma inviare un esempio completo per chiunque di utilizzare!

Non ho intenzione di utilizzare questo nel codice di produzione ... ci sono altri modi di farlo!

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 approccio più semplice è semplicemente non per utilizzare la statica inizializzatore per questo. Perché non basta fare path non-finale e caricarlo in main?

come su questa struttura

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

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

}

Se avete mai rilevare la necessità di riavviare l'applicazione, avere runApplication return true. Se è il momento di falsa uscita di ritorno;

Se si dispone di un'interfaccia utente o un demone in modo da poter controllare allo standard output, si può fare un involucro sul lato esterno che avvia il programma.

Se il programma su uscite di uscita "RESTART", è possibile riavviare il programma di nuovo da questo wrapper. In caso contrario, solo le estremità.

Se si desidera che il modo in puro Java, si può andare con una soluzione con classloader come Peter Lawrey menzionato nel suo post. Prima di andare su questa strada si dovrebbe davvero ripensare il vostro disegno (se è il codice) e rendere il codice capace di ripulire.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top