java हॉट स्वैप तंत्र के माध्यम से रनटाइम पर एक विधि बदलें




runtime hotswap (6)

मान लें कि हमारे पास एक छोटा जावा प्रोग्राम है जिसमें केवल एक वर्ग शामिल है:

public class HelloWorld {

   private static void replacable(int i) {
      System.out.println("Today is a nice day with a number " + i);
   }        

   public static void main(String[] args) throws Exception {
      for(int i = 0; i < 100000; ++i) {
      replacable(i);
      Thread.sleep(500);
   }
}

संकलित और चलाने के बाद, आउटपुट यह होगा:

आज 0 के साथ एक अच्छा दिन है

आज नंबर 1 के साथ एक अच्छा दिन है

आज नंबर 2 के साथ एक अच्छा दिन है

आज नंबर 3 के साथ एक अच्छा दिन है

...

मेरा प्रश्न: क्या रनटाइम पर replacable विधि को स्वैप करने के लिए कुछ तरीका मौजूद है (या क्षितिज पर है)? कुछ replacable एक और संस्करण को replacable नए संस्करण के साथ replacable , इसे संकलित करना और फिर पुराने संस्करण को पहले से चल रहे JVM में लिखना पसंद है?

इसलिए, अगर मैं इस तरह का नया संस्करण लिखता हूं:

private static void replacable(int i) {
   System.out.println("Today is an even nicer day with a number " + i);
}  

क्या एरलांग के हॉट कोड स्वैपिंग के समान कुछ है जहां मैं यह कर सकता हूं:

  1. मूल कार्यक्रम चलाओ
  2. संशोधित संस्करण लिखें
  3. कमांड लाइन प्रोग्राम का उपयोग करके, JVM चलाने और मौजूदा विधि को प्रतिस्थापित करने के लिए कनेक्ट करें

ताकि, रनटाइम के दौरान, यह होगा:

आज 15000 के साथ एक अच्छा दिन है

आज 15001 के साथ एक अच्छा दिन है

आज 15002 के साथ एक अच्छा दिन भी है

आज 15003 नंबर के साथ एक अच्छा दिन भी है

...

मान लें कि उपर्युक्त प्रोग्राम स्टैंडअलोन है, मानक जावा एसई पर्यावरण में चलता है, क्लासपाथ पर कुछ और नहीं है, इसलिए यह लगभग हैलो वर्ल्ड स्टाइल प्रोग्राम है।

नोट: मुझे पता है कि जावा ईई आदि में विधियों की बाइटकोड मैनिपुलेशन ( cglib ), aspectJ , jRebel , JMX , हॉटस्पैपिंग जैसी तकनीकें मौजूद हैं, लेकिन वे नहीं हैं जो मैं सोच रहा हूं। Erlang के बारे में सोचो।


थोड़ा पुराना पोस्ट, लेकिन उम्मीद है कि किसी को यह उपयोगी लगेगा:

मुझे लगता है कि अपेक्षाकृत नया हॉटस्पैप एजेंट अच्छी तरह से प्रलेखित और फीचर समृद्ध है (और सबसे अच्छा, ओपन सोर्स )।


आप इसे कक्षा लोडर के माध्यम से कर सकते हैं। उदाहरण के लिए यदि आप टोमकैट जैसे सर्वलेट कंटेनर से परिचित हैं जो पृष्ठों को फिर से लोड करते हैं जैसे आप उन्हें विकास में संशोधित करते हैं। जावा में गतिशील कोड बनाने का एक महान स्पष्टीकरण यहां दिया गया है। यह न केवल लोडिंग को समझाता है बल्कि फ्लाई पर स्रोत संकलित करता है। आप जिस कोड का उपयोग करना चाहते हैं उसे पुनः लोड करने की किसी भी रणनीति में शामिल अवधारणाओं को लागू करने में सक्षम होना चाहिए।


मैंने कई परियोजनाओं में इस हॉटस्पेप चींटी कार्य का उपयोग किया है। लक्ष्य जावा एप्लिकेशन को एंटी, एक्लिप्स, कमांड प्रॉम्प्ट, या किसी अन्य माध्यम के माध्यम से लॉन्च किया जा सकता है जब तक कि यह उचित बंदरगाह के साथ डीबग मोड में लॉन्च हो जाए। लिंक्ड पेज एंट के माध्यम से इसे कैसे करें इस पर निर्देश प्रदान करता है।

जब तक परिवर्तन संरचनात्मक नहीं होते हैं तब तक कक्षाओं की किसी भी संख्या को हॉटस्पेप किया जा सकता है। विधि शरीर आमतौर पर आसानी से hotswap बदलता है। एक खोल या ग्रहण के माध्यम से एक चींटी स्क्रिप्ट चलाकर कोड को हॉटस्पेप किया जा सकता है।

काम पर, मैं एक स्क्रिप्ट का उपयोग करता हूं जो वर्ग फ़ाइलों पर टाइमस्टैम्प की तुलना करके स्वचालित रूप से कोड बदलता है। यह प्रोजेक्ट पेज पर नमूने के समान है जो एक साधारण उदाहरण दिखाता है कि केवल हॉटस्प्स ने कक्षाओं को बदल दिया है।

अतिरिक्त नोट: यह JPDA का उपयोग करता है।


आप या तो अपने लक्ष्य को आसानी से प्राप्त करने के लिए ओपन-सोर्स हॉटस्पॉट वीएम या वाणिज्यिक JRebel आईडीई प्लगइन का उपयोग कर सकते हैं ( here तुलना तालिका देखें)।


आप स्ट्रैटजी डिज़ाइन पैटर्न का उपयोग कर सकते हैं, इसलिए आपके पास एक विधि के बजाय हेरफेर करने के लिए एक ऑब्जेक्ट है, और प्रोग्राम के साथ संवाद करने के लिए एक प्रोटोकॉल है ताकि उसे किसी ऑब्जेक्ट क्लास नाम को स्ट्रैटजी ऑब्जेक्ट के वर्ग के रूप में उपयोग करने के लिए कहा जा सके।


ओएसजीआई के बारे में क्या? हॉट स्वैपिंग स्पेस में "निर्मित" सॉर्टा है - मुझे लगता है कि यह एक संभावित समाधान भी होगा।





hotswap