重启自己 - 我可以从头开始重新初始化一切吗?

时间:2010-11-17 18:07:46

标签: java restart application-restart

我有这样的事情:

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(...)

可以吗?

6 个答案:

答案 0 :(得分:3)

您可以使用自定义类加载器启动应用程序,这将允许您加载和卸载静态变量。

然而,基本上它是一个非常糟糕的设计需要这样做。我喜欢让田野最终,但如果你想改变它们,你不应该把它们作为最终。

答案 1 :(得分:2)

如果您的目标只是重新加载某些配置文件,为什么不实施文件更改监视器?

这是一个关于这个主题的好教程:

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

我认为你提出的建议(自动重启你的应用程序)比看文件更新要麻烦一些。

答案 2 :(得分:2)

我接受了Peter Lawrey回答,但发布了一个完整的例子供任何人使用!

我不会在生产代码中使用它......还有其他方法可以做到这一点!

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

答案 3 :(得分:1)

更简单的方法是为此使用静态初始化程序。为什么不让path非最终版并将其加载到main

答案 4 :(得分:0)

这个结构怎么样

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

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

}

如果您发现需要重新启动应用程序,请让runApplication返回true。 如果是时候退出返回false;

答案 5 :(得分:0)

如果你有一个UI或一个守护进程,所以你可以控制输出到stdout,你可以在外面创建一个启动程序的包装器。

如果程序在退出时输出“RESTART”,则可以从此包装器重新启动程序。如果没有,它就结束了。

或者如果你想要纯粹的java方式,你可以像Peter Laurerey在帖子中提到的那样使用类加载器的解决方案。在沿着这条路走下去之前,你应该重新考虑你的设计(如果它是你的代码)并使你的代码能够清理自己。