Перезапустите себя - могу ли я повторно поинвизировать все с нуля?

StackOverflow https://stackoverflow.com/questions/4207593

Вопрос

У меня есть что-то подобное:

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

Я хочу поинтерить JVM, вызывая статический инициализатор снова, а затем main(...)!

Это можно сделать?

Это было полезно?

Решение

Вы можете начать свое приложение с помощью пользовательского погрузчика класса, это позволит вам загрузить и разгрузить ваши статические переменные.

Однако в основном это очень плохой дизайн, чтобы нужно сделать это. Мне нравится делать финал поля, но вы не должны делать их окончательными, если вы хотите изменить их.

Другие советы

Если ваша цель - просто перезагрузить некоторые файлы конфигурации, почему бы не реализовать монитор изменения файла?

Вот хороший учебник по этому вопросу:

http://download.orcle.com/javase/tutorial/essential/io/notification.html.

Я думаю, что вы предлагаете (перезапускаете ваше приложение автоматически), будет немного более громоздким, чем просто наблюдать за обновлениями файлов.

Я принимаю Петр Лаури Ответьте, но опубликуйте полный пример для любого в использовании!

Я не собираюсь использовать это в производственном коде ... Есть и другие способы сделать это!

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

Прощественный подход просто нет Чтобы использовать статический инициализатор для этого. Почему бы не просто сделать path не окончательный и загрузить его в main?

Как насчет этой структуры

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

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

}

Если вы когда-либо обнаруживаете необходимость перезапустить приложение, вернуть RunApplication True. Если пришло время выйти из возврата FALSE;

Если у вас есть пользовательский интерфейс или демон, чтобы вы могли контролировать выход на stdout, вы можете сделать обертку снаружи, которая запускает вашу программу.

Если программа при выходе на выход «Перезагрузите», вы можете снова перезагрузить программу с этой обертки. Если нет, это просто заканчивается.

Или если вы хотите чистый Java Way, вы можете пойти с решением с классными загрузками, когда Питер Леври упоминал в его посте. Прежде чем идти по этому маршруту, вы действительно должны переосмыслить ваш дизайн (если это ваш код) и сделать ваш код, способный очистить себя.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top