أعد تشغيل نفسي - هل يمكنني إعادة تهيئة كل شيء من الصفر؟

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.oracle.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();
    }

}

إذا اكتشفت أي وقت مضى الحاجة إلى إعادة تشغيل تطبيقك ، فقم بإرجاع التشغيل الصحيح. إذا حان الوقت للخروج من العودة كاذبة ؛

إذا كان لديك واجهة مستخدم أو خفي حتى تتمكن من التحكم في الإخراج إلى stdout ، فيمكنك إنشاء غلاف من الخارج يبدأ البرنامج.

إذا كان البرنامج عند الخروج يخرج "إعادة التشغيل" ، فيمكنك إعادة تشغيل البرنامج مرة أخرى من هذا الغلاف. إذا لم يكن كذلك ، فإنه ينتهي فقط.

أو إذا كنت تريد طريقة Java النقية ، فيمكنك الذهاب مع حل مع قائدي Classloads كما ذكر بيتر لوري في منصبه. قبل السير في هذا المسار ، يجب أن تعيد التفكير في التصميم الخاص بك (إذا كان هذا الكود) وجعل الكود الخاص بك قادرًا على تنظيف نفسه.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top