自分自身を再起動します - 私は最初からすべてを再初期化することができますか?

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(...)したいです!

はそれを行うことができますか?

役に立ちましたか?

解決

あなたはカスタムクラスローダを使用してアプリケーションを起動することができ、これはあなたの静的変数をロードし、アンロードすることができます。

しかし、基本的にはそのA非常に悪いデザインは、これを実行する必要があります。 Iフィールドは、最終的な作りのような、しかし、あなたがそれらを変更したい場合、あなたは彼らが最終的にするべきではありません。

他のヒント

あなたの目標は、いくつかの設定ファイルをリロードするだけであれば、なぜファイルの変更監視を実装していない?

ここでは、このテーマに関する優れたチュートリアルがあります:

http://download.oracle.com/javase/tutorial/不可欠/ IO / notification.htmlする

私は、ファイルの更新のために見ているよりも少し面倒になり、あなたが提案(自動的にアプリケーションを再起動)しているものだと思います。

私はピーター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);
        }
    }
}

簡単な方法は、単純である、のないのこのため初期化子、静的を使用します。理由だけではなく、pathの非最終作り、mainでそれをロードしませんか?

どのようにこの構造について

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

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

}

あなたは今までrunApplicationがtrueを返す必要があり、あなたのアプリケーションを再起動する必要性を検出した場合。 それが出口リターンfalseに時間がある場合は、

あなたがstdoutに出力を制御できるように、UIやデーモンを持っている場合は、

、あなたはあなたのプログラムを起動する外部のラッパーを作ることができます。

の終了時に出力プログラム「RESTARTは、」あなたはこのラッパーからもう一度プログラムを再起動することができます。そうでない場合は、それだけで終了します。

それとも、純粋なJavaの道をしたい場合、あなたはピーターLawreyは彼のポストで述べたようにクラスローダとの溶液で行くことができます。このルートを下って行く前に、あなたは本当に(それはあなたのコードの場合)、あなたのデザインを再考し、自分自身をクリーンアップのあなたのコードは可能にする必要があります。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top