自分自身を再起動します - 私は最初からすべてを再初期化することができますか?
-
25-09-2019 - |
質問
私はこのようなものを持っています:
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に時間がある場合は、
、あなたはあなたのプログラムを起動する外部のラッパーを作ることができます。
の終了時に出力プログラム「RESTARTは、」あなたはこのラッパーからもう一度プログラムを再起動することができます。そうでない場合は、それだけで終了します。
それとも、純粋なJavaの道をしたい場合、あなたはピーターLawreyは彼のポストで述べたようにクラスローダとの溶液で行くことができます。このルートを下って行く前に、あなたは本当に(それはあなたのコードの場合)、あなたのデザインを再考し、自分自身をクリーンアップのあなたのコードは可能にする必要があります。