मैं एक जावा एप्लिकेशन कैसे लिख सकता हूं जो रनटाइम में खुद को अपडेट कर सकता है?


91

मैं एक जावा एप्लिकेशन (सर्वर एप्लिकेशन) को लागू करना चाहूंगा जो किसी दिए गए यूआरएल से एक नया संस्करण (.jar फ़ाइल) डाउनलोड कर सकता है, और फिर रनटाइम पर खुद को अपडेट कर सकता है।

ऐसा करने का सबसे अच्छा तरीका क्या है और क्या यह संभव है?

मुझे लगता है कि एप्लिकेशन एक नई .jar फ़ाइल डाउनलोड कर सकता है और इसे शुरू कर सकता है। लेकिन मुझे हैंडओवर कैसे करना चाहिए, उदाहरण के लिए पता है कि नया एप्लिकेशन कब शुरू किया जाता है और फिर बाहर निकल जाता है। या ऐसा करने का एक बेहतर तरीका है?


4
क्या आपने जावा वेब स्टार्ट को देखा है? यह रनटाइम पर खुद को अपडेट नहीं करता है, मेरा मानना ​​है कि, (पुनः आरंभ आवश्यक), इसके लिए आपको संभवतः OSGi को देखना होगा।
थिलो

@ थिलो: मुझे लगता है कि किसी दिए गए url से फ़ाइल डाउनलोड करना आसान होगा, और फिर इसे रनिंग जार फ़ाइल से एक linux कमांड से शुरू करें।
जोनास

1
जावा वेबस्टार्ट एपीआई का डिज़ाइन चलते समय अद्यतन करना असंभव बनाता है। दुर्भाग्य से।
थोरबजोरन रावन एंडरसन


@ अमीन बॉस आप रॉक करते हैं, आपने मेरा दिन बना दिया :)
iltaf खालिद

जवाबों:


68

एक समाधान की मूल संरचना इस प्रकार है:

  • ऐप के नवीनतम संस्करण (यदि आवश्यक हो) को बार-बार लोड करने और इसे लॉन्च करने के लिए एक मुख्य लूप जिम्मेदार है।

  • एप्लिकेशन अपनी बात करता है, लेकिन समय-समय पर डाउनलोड URL की जांच करता है। यदि यह एक नए संस्करण का पता लगाता है तो यह लॉन्चर में वापस आ जाता है।

ऐसे कई तरीके हैं जिनसे आप इसे लागू कर सकते हैं। उदाहरण के लिए:

  • लांचर एक रैपर स्क्रिप्ट या बाइनरी एप्लिकेशन हो सकता है जो कि एक JAR फ़ाइल से एप्लिकेशन को चलाने के लिए एक नया JVM शुरू करता है जो प्रतिस्थापित हो जाता है।

  • लांचर एक जावा अनुप्रयोग हो सकता है जो नए JAR के लिए एक क्लास लोडर बनाता है, एक एंट्रीपॉइंट क्लास को लोड करता है और उस पर कुछ विधि कहता है। यदि आप इसे इस तरह करते हैं, तो आपको क्लास लोडर स्टोरेज लीक के लिए देखना होगा, लेकिन यह मुश्किल नहीं है। (आपको बस यह सुनिश्चित करने की आवश्यकता है कि जार से लोड की गई कक्षाओं वाली कोई भी वस्तु आपके पुनः जारी करने के बाद उपलब्ध नहीं है।)

बाहरी आवरण दृष्टिकोण के लाभ हैं:

  • आपको केवल एक JAR की आवश्यकता है,
  • आप पूरे जावा ऐप को बदल सकते हैं,
  • एप्लिकेशन द्वारा बनाए गए किसी भी माध्यमिक धागे, आदि विशेष शटडाउन तर्क के बिना चले जाएंगे, और
  • तुम भी आवेदन दुर्घटनाओं, आदि से वसूली के साथ सौदा कर सकते हैं

दूसरे दृष्टिकोण के लिए दो JAR की आवश्यकता होती है, लेकिन इसके निम्नलिखित फायदे हैं:

  • समाधान शुद्ध जावा और पोर्टेबल है,
  • बदलाव तेज होगा, और
  • आप पुनः आरंभ (मॉडुलो लीकेज मुद्दों) पर अधिक आसानी से स्थिति बनाए रख सकते हैं।

"सबसे अच्छा" तरीका आपकी विशिष्ट आवश्यकताओं पर निर्भर करता है।

यह भी ध्यान दिया जाना चाहिए कि:

  • ऑटो-अद्यतन के साथ सुरक्षा जोखिम हैं। सामान्य तौर पर, यदि अपडेट प्रदान करने वाले सर्वर से छेड़छाड़ की जाती है, या यदि अपडेट प्रदान करने वाले तंत्र पर हमला करने की आशंका होती है, तो ऑटो-अपडेट करने से क्लाइंट (एस) का समझौता हो सकता है।

  • क्लाइंट को नुकसान पहुंचाने वाले क्लाइंट को अपडेट देने से कानूनी जोखिम हो सकता है, और आपके व्यवसाय की प्रतिष्ठा को जोखिम हो सकता है।


यदि आप पहिये को फिर से लगाने से बचने का एक तरीका खोज सकते हैं, तो यह अच्छा होगा। सुझावों के लिए अन्य उत्तर देखें।


43

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

अपडेटर में अपडेटर एप्लिकेशन को ही पैक करें।

अनुप्रयोग : जब अनुप्रयोग एक नए संस्करण का पता लगाता है, तो यह निम्न कार्य करता है:

  1. डाउनलोड अपडेट (ज़िपफाइल)
  2. निकालें आवेदन और ApplicationUpdater (सभी zipfile में)
  3. अपडाउनर चलाएं

ApplicationUpdater : जब अपडेटर चलता है तो यह निम्न कार्य करता है:

  1. आवेदन बंद करो (मेरे मामले में init.d के माध्यम से एक डेमन)
  2. वर्तमान एप्लिकेशन को अधिलेखित करने के लिए डाउनलोड की गई जार फ़ाइल की प्रतिलिपि बनाएँ
  3. अनुप्रयोग प्रारंभ करें
  4. साफ - सफाई।

आशा है कि यह किसी की मदद करता है।


12

यह एक ज्ञात समस्या है और मैं एक पहिया को फिर से शुरू करने के खिलाफ सलाह देता हूं - अपनी खुद की हैक को न लिखें, केवल अन्य लोगों ने जो किया है उसका उपयोग करें।

दो स्थितियों पर विचार करने की आवश्यकता है:

  1. ऐप को स्व-अद्यतन करने योग्य होना चाहिए और अपडेट (सर्वर ऐप, एम्बेडेड ऐप) के दौरान भी चालू रहना चाहिए। OSGi के साथ जाएं: बंडल या इक्विनॉक्स P2

  2. ऐप एक डेस्कटॉप ऐप है और इसमें इंस्टॉलर है। अपडेट विकल्प के साथ कई इंस्टॉलर हैं। इंस्टॉलर्स सूची की जाँच करें ।


12

मैंने हाल ही में अद्यतन 4j बनाया है जो जावा 9 के मॉड्यूल सिस्टम के साथ पूरी तरह से संगत है।

यह बिना किसी पुनरारंभ के नए संस्करण को मूल रूप से शुरू कर देगा।


एक बूटस्ट्रैप / व्यावसायिक अनुप्रयोग प्रतिमान का उपयोग करके। बूटस्ट्रैप व्यवसाय एप्लिकेशन को लोड और अनलोड करता है और यह बूटस्ट्रैप है जो आम तौर पर अपडेट करता है।
मोर्देखाई

10

मैंने एक जावा एप्लिकेशन लिखा है जो प्लगइन्स को रनटाइम पर लोड कर सकता है और जेईडिट में एक समान तंत्र से प्रेरित होकर तुरंत उनका उपयोग करना शुरू कर सकता है। jEdit ओपन सोर्स है इसलिए आपके पास यह देखने का विकल्प है कि यह कैसे काम करता है।

समाधान जार से फ़ाइलों को लोड करने के लिए एक कस्टम ClassLoader का उपयोग करता है। एक बार जब वे लोड हो जाते हैं तो आप नए जार से कुछ विधि लागू कर सकते हैं जो इसकी mainविधि के रूप में कार्य करेगी । फिर मुश्किल हिस्सा यह सुनिश्चित कर रहा है कि आप पुराने कोड के सभी संदर्भों से छुटकारा पा लें ताकि इसे इकट्ठा किया जा सके। मैं उस हिस्से पर काफी विशेषज्ञ नहीं हूं, मैंने इसे काम कर दिया है लेकिन यह आसान नहीं था।


मैं जावा के बारे में नहीं जानता, लेकिन C # में, आप स्पष्ट रूप से कोड को अनलोड करने के लिए AppDomains का उपयोग कर सकते हैं। शायद जावा में एक समान अवधारणा है।
मेरलिन मॉर्गन-ग्राहम

1
धन्यवाद, यह जाने का रास्ता प्रतीत होता है। क्लासडैडर केNetworkClassLoader लिए जावाडॉक
जोनास

क्या आपने उसी जेवीएम के भीतर स्थिर चर के साथ समस्याओं में भाग लिया, या स्थायी पीढ़ी के बारे में क्या? मैंने सुना है कि ये कक्षा उतारने के संबंध में मुद्दे पेश कर सकते हैं।
आईडीई

5
  1. पहला तरीका: टॉमकैट का उपयोग करें और यह सुविधाओं को तैनात करता है।
  2. दूसरा तरीका: एप्लिकेशन को दो भागों (कार्यात्मक और अपडेट) पर विभाजित करने के लिए और अपडेट भाग को फ़ंक्शन भाग को बदलने दें।
  3. तीसरा तरीका: आपके सर्वर में केवल नया संस्करण डाउनलोड करने की अपील है, तो पुराना संस्करण बाध्य पोर्ट जारी करता है, फिर पुराना संस्करण नया संस्करण चलाता है (प्रक्रिया शुरू करता है), फिर पुराना संस्करण पुराने संस्करण को हटाने के लिए नए संस्करण के लिए एप्लिकेशन पोर्ट पर एक अनुरोध भेजता है, पुराना संस्करण समाप्ति और नया संस्करण पुराने संस्करण को हटा देता है। इस कदर: वैकल्पिक शब्द

आपका दूसरा तरीका एक दिलचस्प डिजाइन लगता है।
जोनास

2

यह जरूरी नहीं कि सबसे अच्छा तरीका है, लेकिन यह आपके लिए काम कर सकता है।

आप एक बूटस्ट्रैप एप्लिकेशन लिख सकते हैं (यदि आप वाह खेल चुके हैं, तो Warcraft लांचर की दुनिया के बारे में)। वह बूटस्ट्रैप अद्यतन के लिए जाँच के लिए जिम्मेदार है।

  • यदि कोई अपडेट उपलब्ध है, तो वह इसे उपयोगकर्ता को प्रदान करेगा, डाउनलोड, इंस्टॉलेशन आदि को हैंडल करेगा।
  • यदि एप्लिकेशन अद्यतित है, तो यह उपयोगकर्ता को एप्लिकेशन लॉन्च करने की अनुमति देगा
  • वैकल्पिक रूप से, आप उपयोगकर्ता को एप्लिकेशन लॉन्च करने की अनुमति दे सकते हैं, भले ही वह अद्यतित न हो

इस तरह आपको अपने आवेदन से बाहर निकलने के लिए परेशान होने की जरूरत नहीं है।

यदि आपका आवेदन वेब आधारित है, और यदि यह महत्वपूर्ण है कि उनके पास अप टू डेट क्लाइंट है, तो आप आवेदन चलाने के दौरान संस्करण की जांच भी कर सकते हैं। आप सर्वर (कुछ या सभी कॉल), या दोनों के साथ सामान्य संचार करते हुए, उन्हें अंतराल पर कर सकते हैं।

एक उत्पाद के लिए जिस पर मैंने हाल ही में काम किया था, हमने लॉन्च पर (बिना बूट स्ट्रैपर ऐप के, लेकिन मुख्य विंडो दिखाई देने से पहले) और सर्वर पर कॉल के दौरान संस्करण की जाँच की। जब ग्राहक पुराना था, तो हमने उपयोगकर्ता को मैन्युअल रूप से छोड़ने पर भरोसा किया, लेकिन सर्वर के खिलाफ कोई भी कार्रवाई करने से मना किया।

कृपया ध्यान दें कि मुझे पता नहीं है कि क्या जावा आपके मुख्य विंडो को लाने से पहले यूआई कोड को लागू कर सकता है। हम C # / WPF का उपयोग कर रहे थे।


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

जब आप "सर्वर एप्लिकेशन" कहते हैं, तो क्या आपका मतलब है कि यह एक ऐसा एप्लिकेशन है जो सीधे लॉग ऑन करते समय सर्वर पर चलाया जाता है?
मेरलिन मॉर्गन-ग्राहम

@ जोनास: मैं बहुत कुछ नहीं समझता कि कैसे .jar फाइलें काम करती हैं, इसलिए मैं वहां ज्यादा सेवा नहीं कर सकता। मैं समझ सकता हूं कि क्या आप जावा के लिए विशिष्ट जवाब पसंद करेंगे। उम्मीद है कि यह आपको विचार के लिए भोजन देता है, कम से कम :)
मर्लिन मॉर्गन-ग्राहम

@ मर्लिन: मैं आपके विचारों को साझा करने के लिए आभारी हूं। हां, यह एक जावा एप्लिकेशन है जो लिनक्स सर्वर पर चल रहा है, और कोई भी उस सर्वर पर लॉग इन नहीं होता है।
जोनास

1
@ जोनास: ऐसा नहीं है कि आपने पहले से ही इस बारे में नहीं सोचा था, लेकिन - अधिकांश वेब सेवाओं पर मैंने एक मैनुअल तैनाती की रणनीति देखी है। आप इस बारे में सावधान रहना चाहते हैं कि आप अपडेट के लिए कैसे जांच करेंगे। यदि आप छोटी गाड़ी / टूटी हुई कोड को धक्का देते हैं, या केवल w / एक मल्टी-फ़ाइल परिनियोजित तरीके से भाग लेते हैं, तो सर्वर स्वयं को अपडेट करने का प्रयास कर सकता है, और फिर आपके पास एक टूटा हुआ सर्वर होगा।
मेरलिन मॉर्गन-ग्राहम

2

यदि आप इक्विनॉक्स प्लगइन्स का उपयोग करके अपने एप्लिकेशन का निर्माण करते हैं , तो आप इस समस्या के लिए तैयार समाधान प्राप्त करने के लिए पी 2 प्रोविजनिंग सिस्टम का उपयोग कर सकते हैं । इससे सर्वर को अपडेट के बाद खुद को रिस्टार्ट करना होगा।


1

मैं एक नया जार (आदि) डाउनलोड करते समय एक सुरक्षा समस्या देखता हूं, उदाहरण के लिए, मध्य हमले में एक आदमी। आपको हमेशा अपने डाउनलोड करने योग्य अपडेट पर हस्ताक्षर करना होगा।

JAX2015 पर, एडम बायन ने बायनेरिज़ को अपडेट करने के लिए JGit का उपयोग करने के बारे में बताया। अफसोस की बात है कि मुझे कोई ट्यूटोरियल नहीं मिला।

स्रोत जर्मन में

एडम बिएन ने यहां अपडेटर को बनाया

मैंने इसे कुछ javafx के साथ यहाँ फोर्क किया । मैं एक स्वचालित हस्ताक्षर पर भी काम कर रहा हूं।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.