Frage

Ich habe so etwas wie folgt aus:

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

Ich möchte, dass die JVM den Aufruf der statischen neu zu initialisieren initializer wieder, und dann main(...)!

Kann es getan werden?

War es hilfreich?

Lösung

Sie können Ihre Anwendung mit einem benutzerdefinierten Class Loader starten, dies ermöglicht es Ihnen, Ihre statischen Variablen zu laden und zu entladen.

Doch im Grunde ist es ein sehr schlechtes Design zu Notwendigkeit, dies zu tun. Ich mag Felder endgültig zu machen, aber man sollte sie nicht endgültig, wenn Sie sie ändern möchten.

Andere Tipps

Wenn Ihr Ziel ist einfach, einige Konfigurationsdateien neu zu laden, warum eine Datei nicht ändern Monitor implementieren?

Hier ist ein gutes Tutorial zu diesem Thema:

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

Ich denke, was Sie vorschlagen (Neustart der Anwendung automatisch) ein wenig umständlicher als nur gerade für Datei-Updates sein würde.

Ich bin zu akzeptieren Peter Lawrey > Antwort, aber ein vollständiges Beispiel für jedermann zu benutzen schreiben!

Ich werde nicht diesen Code in der Produktion verwenden ... es gibt andere Möglichkeiten, es zu tun!

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

Ein einfacher Ansatz ist einfach nicht , um die statische Aufladung zu verwenden initializer dafür. Warum nicht einfach path nicht endgültig und laden Sie es in main machen?

Wie über diese Struktur

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

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

}

Wenn Sie jemals die Notwendigkeit erkennen Sie Anwendung neu starten, haben RunApplication true zurück. Wenn es Zeit ist, zu verlassen return false;

Wenn Sie eine Benutzeroberfläche oder einen Daemon, so dass Sie auf stdout steuern können, können Sie einen Wrapper auf der Außenseite, die Ihr Programm startet.

Wenn das Programm beim Verlassen Ausgängen „NEUSTART“ Sie Ihr Programm wieder von diesem Wrapper neu starten kann. Wenn nicht, ist es nur Ende.

Oder wenn Sie die reine Java Art und Weise möchten, können Sie mit einer Lösung mit Classloader gehen, wie Peter Lawrey in seinem Beitrag erwähnt. Vor diesem Weg geht nach unten sollten Sie wirklich Ihr Design überdenken (wenn es Ihr Code) und stellen Sie den Code der Lage Reinigung selbst auf.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top