1

私はこのようなものを持っています:

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

それはできますか?

4

6 に答える 6

3

カスタム クラス ローダーを使用してアプリケーションを起動できます。これにより、静的変数をロードおよびアンロードできます。

ただし、基本的にこれを行う必要があるのは非常に悪い設計です。フィールドを final にするのは好きですが、変更したい場合は final にしないでください。

于 2010-11-17T20:04:41.357 に答える
2

単にいくつかの構成ファイルをリロードすることが目的である場合、ファイル変更モニターを実装してみませんか?

この件に関する優れたチュートリアルは次のとおりです。

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

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

于 2010-11-17T18:12:51.427 に答える
1

より単純なアプローチは、静的イニシャライザを使用しないことです。pathnon-final を作成してロードしないのはなぜmainですか?

于 2010-11-17T18:12:31.803 に答える
1

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);
        }
    }
}
于 2010-11-18T10:55:46.777 に答える
0

この構造はどうですか

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

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

}

アプリケーションを再起動する必要があることを検出した場合は、runApplicationがtrueを返すようにします。終了するときはfalseを返します。

于 2010-11-17T19:29:01.227 に答える
0

標準出力への出力を制御できる UI またはデーモンがある場合は、外部でプログラムを開始するラッパーを作成できます。

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

または、純粋な Java の方法が必要な場合は、Peter Lawrey が彼の投稿で述べたように、クラスローダーを使用したソリューションを使用できます。このルートをたどる前に、(それがコードの場合) 設計を再考し、コード自体をクリーンアップできるようにする必要があります。

于 2010-11-17T20:15:12.680 に答える