Question

J'ai quelque chose comme ceci:

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

Je veux réinitialiser la machine virtuelle Java appelle à nouveau l'initialiseur statique, puis main(...)!

Peut-il être fait?

Était-ce utile?

La solution

Vous pouvez commencer votre application à l'aide d'un chargeur de classe personnalisée, cela vous permettra de charger et de décharger vos variables statiques.

Cependant, au fond de son design très mauvais besoin de le faire. J'aime faire des champs finale, mais vous ne devriez pas les faire finale si vous voulez les modifier.

Autres conseils

Si votre objectif est simplement de recharger certains fichiers de configuration, pourquoi ne pas mettre en œuvre un changement de fichier moniteur?

Voici un bon tutoriel sur ce sujet:

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

Je pense que ce que vous proposez (redémarrer votre application automatiquement) serait un peu plus lourd que simplement regarder des mises à jour de fichiers.

Je suis d'accepter Peter Lawrey réponse, mais poster un exemple complet pour quiconque d'utiliser!

Je ne vais pas l'utiliser dans le code de production ... il y a d'autres façons de le faire!

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

Une approche plus simple est simplement pas pour utiliser l'initialiseur statique pour cela. Pourquoi ne pas simplement faire path non-finale et le charger dans main?

Que diriez-vous de cette structure

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

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

}

Si vous détectez la nécessité de redémarrer votre application, ont runApplication return true. S'il est temps de quitter return false;

Si vous avez une interface utilisateur ou un démon afin que vous puissiez contrôler la sortie à stdout, vous pouvez faire une enveloppe à l'extérieur qui commence votre programme.

Si le programme sur les sorties de sortie « Restart », vous pouvez redémarrer votre programme à nouveau de cette enveloppe. Sinon, il se termine juste.

Ou si vous voulez que la façon pure java, vous pouvez aller avec une solution avec classloaders comme Peter Lawrey mentionné dans son poste. Avant d'aller dans cette voie, vous devriez vraiment repenser votre conception (si elle est votre code) et rendre votre code capable de se nettoyer.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top