जावा क्लासलोडर: Difference between revisions

From Vigyanwiki
Line 75: Line 75:
== जार हेल ==
== जार हेल ==
जार हेल [[डीएलएल नरक|डीएलएल हेल]] के समान एक शब्द है जिसका उपयोग उन सभी विभिन्न प्रकारों का वर्णन करने के लिए किया जाता है जिनमें क्लासलोडिंग प्रक्रिया कार्य नहीं कर सकती है।<ref>{{Cite web|url=http://incubator.apache.org/depot/version/jar-hell.html|archive-url = https://web.archive.org/web/20130601002059/http://incubator.apache.org/depot/version/jar-hell.html|archive-date = 2013-06-01|title = Depot - Apache Incubator}}</ref> तीन प्रकार से जार हेल उत्पन्न हो सकता है:
जार हेल [[डीएलएल नरक|डीएलएल हेल]] के समान एक शब्द है जिसका उपयोग उन सभी विभिन्न प्रकारों का वर्णन करने के लिए किया जाता है जिनमें क्लासलोडिंग प्रक्रिया कार्य नहीं कर सकती है।<ref>{{Cite web|url=http://incubator.apache.org/depot/version/jar-hell.html|archive-url = https://web.archive.org/web/20130601002059/http://incubator.apache.org/depot/version/jar-hell.html|archive-date = 2013-06-01|title = Depot - Apache Incubator}}</ref> तीन प्रकार से जार हेल उत्पन्न हो सकता है:
* किसी सिस्टम पर संस्थापित लाइब्रेरी के दो भिन्न-भिन्न संस्करणों (वर्शन) की आकस्मिक उपस्थिति। इसे सिस्टम द्वारा त्रुटि नहीं माना जाएगा। अपितु, सिस्टम किसी न किसी लाइब्रेरी से क्लासेस लोड करेगा। नई लाइब्रेरी को प्रतिस्थापित करने के स्थान पर उसे उपलब्ध लाइब्रेरी की सूची में संबद्ध करने से हो सकता है कि एप्लिकेशन अभी भी ऐसा व्यवहार कर रहा हो जैसे कि पुरानी लाइब्रेरी उपयोग में है जो कि हो भी सकती है।
* किसी सिस्टम पर संस्थापित (इन्सटाल्ड) लाइब्रेरी के दो भिन्न-भिन्न संस्करणों (वर्शन) की आकस्मिक उपस्थिति। इसे सिस्टम द्वारा त्रुटि नहीं माना जाएगा। अपितु, सिस्टम किसी न किसी लाइब्रेरी से क्लासेस लोड करेगा। नई लाइब्रेरी को प्रतिस्थापित करने के स्थान पर उसे उपलब्ध लाइब्रेरी की सूची में संबद्ध करने से हो सकता है कि एप्लिकेशन अभी भी ऐसा व्यवहार कर रहा हो जैसे कि पुरानी लाइब्रेरी उपयोग में है जो कि हो भी सकती है।
* एक से अधिक लाइब्रेरी या एप्लिकेशन को लाइब्रेरी फू के विभिन्न संस्करणों की आवश्यकता होती है। यदि लाइब्रेरी फू के संस्करण समान क्लास नामों का उपयोग करते हैं तो लाइब्रेरी फू के संस्करणों को उसी क्लास लोडर के साथ लोड करने का कोई अन्य उपाय नहीं है।
* एक से अधिक लाइब्रेरी या एप्लिकेशन को लाइब्रेरी फू के विभिन्न संस्करणों की आवश्यकता होती है। यदि लाइब्रेरी फू के संस्करण समान क्लास नामों का उपयोग करते हैं तो लाइब्रेरी फू के संस्करणों को उसी क्लास लोडर के साथ लोड करने का कोई अन्य उपाय नहीं है।
* अत्यधिक जटिल JAR हेल की समस्याएँ उन परिस्थितियों में उत्पन्न होती हैं जो क्लासलोडिंग सिस्टम की पूर्ण जटिलता का लाभ उठाती हैं। एक जावा प्रोग्राम के लिए केवल एक "फ्लैट" क्लास लोडर का उपयोग करना आवश्यक नहीं है, अपितु इसमें अनेक (संभवतः बहुत अधिक) नेस्टेड सहयोगी क्लास लोडर समाहित हो सकते है। विभिन्न क्लास लोडर द्वारा लोड की गई क्लासेस जटिल प्रकारों से एक दूसरे को प्रभावित कर सकती हैं जो किसी डेवलपर द्वारा पूर्णतया समझ में नहीं आती हैं, जिससे त्रुटियां या बग उत्पन्न होते हैं तथा जिनका विश्लेषण, व्याख्या तथा हल करना कठिन होता है।<ref>{{Cite web|url=http://articles.qos.ch/classloader.html|title=Taxonomy of class loader problems with Jakarta Commons Logging}}</ref>
* अत्यधिक जटिल JAR हेल की समस्याएँ उन परिस्थितियों में उत्पन्न होती हैं जो क्लासलोडिंग सिस्टम की पूर्ण जटिलता का लाभ उठाती हैं। एक जावा प्रोग्राम के लिए केवल एक "फ्लैट" क्लास लोडर का उपयोग करना आवश्यक नहीं है, अपितु इसमें अनेक (संभवतः बहुत अधिक) नेस्टेड, सहयोगी क्लास लोडर समाहित हो सकते है। विभिन्न क्लास लोडर द्वारा लोड की गई क्लासेस जटिल प्रकारों से एक दूसरे को प्रभावित कर सकती हैं जो किसी डेवलपर द्वारा पूर्णतया समझ में नहीं आती हैं, जिससे त्रुटियां या बग उत्पन्न होते हैं तथा जिनको एनालाइज, एक्सप्लेन तथा रिसॉल्व करना कठिन होता है।<ref>{{Cite web|url=http://articles.qos.ch/classloader.html|title=Taxonomy of class loader problems with Jakarta Commons Logging}}</ref>
[[ओएसजीआई]] ने निर्दिष्ट किया (वर्ष 1998 में जेएसआर 8 के रूप में प्रारम्भ) एक मॉड्यूलरिटी संरचना जिसका उद्देश्य एमई, एसई और ईई में वर्तमान और भविष्य के वीएम के लिए जेएआर हेल का समाधान करना है जिसे व्यापक रूप से अपनाया गया है। JAR अभिव्यक्ति (मेनिफेस्ट) में मेटाडेटा का उपयोग करके JAR फ़ाइलें (जिन्हें बंडल कहा जाता है) को प्रति-पैकेज के आधार पर युग्मित किया जाता है। बंडल पैकेज का निर्यात और आयात कर सकते हैं तथा मॉड्यूलरिटी और संस्करण निर्भरता प्रबंधन की मूलभूत संरचनाएं प्रदान करके पैकेज को व्यक्तिगत रख सकते हैं।
[[ओएसजीआई]] ने निर्दिष्ट किया (वर्ष 1998 में जेएसआर 8 के रूप में प्रारम्भ) एक मॉड्यूलरिटी संरचना जिसका उद्देश्य एमई, एसई और ईई में वर्तमान और भविष्य के वीएम के लिए जेएआर हेल का समाधान करना है जिसे व्यापक रूप से अपनाया गया है। JAR अभिव्यक्ति (मेनिफेस्ट) में मेटाडेटा का उपयोग करके JAR फ़ाइलें (जिन्हें बंडल कहा जाता है) को प्रति-पैकेज के आधार पर युग्मित किया जाता है। बंडल पैकेज का निर्यात और आयात कर सकते हैं तथा मॉड्यूलरिटी और संस्करण निर्भरता प्रबंधन की मूलभूत संरचनाएं प्रदान करके पैकेज को व्यक्तिगत रख सकते हैं।


Line 94: Line 94:
  |publisher=[[Oracle Corporation]]
  |publisher=[[Oracle Corporation]]
  |accessdate=2015-11-29
  |accessdate=2015-11-29
}}</ref> के रूप में रीबूट किया गया, जिसे जावा 9 में सम्मिलित किया गया था। वर्ष 2017 में विमोचित, इसमें "जावा प्लेटफ़ॉर्म मॉड्यूल सिस्टम" नामक मॉड्यूलर सॉफ़्टवेयर के लिए समर्थन सम्मिलित है जिसे मॉड्यूल-info.java फ़ाइलों के साथ स्रोत स्तर पर नियंत्रित किया जाता है। यह ओएसजीआई आर्किटेक्चर से एक भिन्न सिद्धांत का पालन करता है जिसका उद्देश्य जावा रनटाइम एनवायरनमेंट के लिए बैकवर्ड-संगत प्रकार से मॉड्यूलरिटी प्रदान करना है जो जेआरई द्वारा प्रदान की जाने वाली लोडिंग क्लासेस के स्वतः निर्धारित (डिफ़ॉल्ट) प्रक्रिया का उपयोग करता है। हालाँकि, चूंकि यह विभिन्न संस्करणों के साथ लाइब्रेरीज़ के नियंत्रित सह-उपस्थिति की क्षमता प्रदान नहीं करता है, इसलिए यह JAR हेल की समस्या से निपटने के लिए उपयुक्त नहीं है।<ref>{{cite web|first1=Neil|last1=Bartlett|first2=Kai|last2=Hackbarth|title=Java 9, OSGi and the Future of Modularity (Part 1)
}}</ref> के रूप में रीबूट किया गया, जिसे जावा 9 में सम्मिलित किया गया था। वर्ष 2017 में विमोचित, इसमें "जावा प्लेटफ़ॉर्म मॉड्यूल सिस्टम" नामक मॉड्यूलर सॉफ़्टवेयर के लिए समर्थन सम्मिलित है जिसे मॉड्यूल-info.java फ़ाइलों के साथ सोर्स लेवल पर नियंत्रित किया जाता है। यह ओएसजीआई आर्किटेक्चर से एक भिन्न सिद्धांत का पालन करता है जिसका उद्देश्य जावा रनटाइम एनवायरनमेंट के लिए बैकवर्ड-कम्पटीएबेल मॉड्यूलरिटी प्रदान करना है जो जेआरई द्वारा प्रदान की जाने वाली लोडिंग क्लासेस के डिफ़ॉल्ट प्रक्रिया का उपयोग करता है। हालाँकि, चूंकि यह विभिन्न संस्करणों के साथ लाइब्रेरीज़ के नियंत्रित सह-उपस्थिति की क्षमता प्रदान नहीं करता है, इसलिए यह JAR हेल की समस्या से निपटने के लिए उपयुक्त नहीं है।<ref>{{cite web|first1=Neil|last1=Bartlett|first2=Kai|last2=Hackbarth|title=Java 9, OSGi and the Future of Modularity (Part 1)
|url=https://www.infoq.com/articles/java9-osgi-future-modularity/#1|publisher=InfoQ|date=2016-09-22}}</ref>
|url=https://www.infoq.com/articles/java9-osgi-future-modularity/#1|publisher=InfoQ|date=2016-09-22}}</ref>
==यह भी देखें==
==यह भी देखें==
* [[लोडर (कंप्यूटिंग)]]
* [[लोडर (कंप्यूटिंग)]]
* गतिक लोडिंग
* डाइनामिक लोडिंग
* डीएलएल हेल
* डीएलएल हेल
* ओएसजीआई
* ओएसजीआई

Revision as of 21:03, 20 July 2023

जावा क्लास लोडर जावा रनटाइम एनवायरनमेंट का एक भाग है जो जावा क्लास को जावा वर्चुअल मशीन में डाइनामिकाली लोड करता है।[1] सामान्यतः क्लासेस केवल अनुरोध पर ही लोड की जाती हैं। वर्चुअल मशीन केवल प्रोग्राम को निष्पादित करने के लिए आवश्यक क्लास फ़ाइल को लोड करेगी।[2] जावा रन टाइम सिस्टम को फ़ाइल और फ़ाइल सिस्टम के विषय में परिचित होने की आवश्यकता नहीं है क्योंकि यह क्लास लोडर को प्रत्यायोजित किया गया है।

एक सॉफ़्टवेयर लाइब्रेरी (कंप्यूटिंग) संबंधित ऑब्जेक्ट कोड का एक संग्रह है। जावा (प्रोग्रामिंग लैंग्वेज) में, लाइब्रेरीज़ को सामान्यतः JAR फ़ाइलों में पैक किया जाता है। लाइब्रेरी में विभिन्न प्रकार के ऑब्जेक्ट हो सकते हैं। जार फ़ाइल में सम्मिलित ऑब्जेक्ट का अधिक महत्वपूर्ण प्रकार जावा क्लास है। एक क्लास को यूनिट ऑफ़ कोड के रूप में विचारा जा सकता है। क्लास लोडर लाइब्रेरी का स्थान निर्धारण, उनकी विषय सूची का अध्ययन तथा लाइब्रेरी के भीतर उपस्थित क्लासेस को लोड करने के लिए उत्तरदायी है। यह लोडिंग सामान्यतः "ऑन डिमांड" की जाती है, ऐसा तब तक नहीं होता है जब तक प्रोग्राम द्वारा क्लास को कॉल नहीं किया जाता है। किसी नामित क्लास को दिए गए क्लास लोडर द्वारा केवल एक बार लोड किया जा सकता है।

प्रत्येक जावा क्लास को क्लास लोडर द्वारा ही लोड किया जाना चाहिए।[3][4] इसके अतिरिक्त, जावा (सॉफ़्टवेयर प्लेटफ़ॉर्म) एक्सटर्नल लाइब्रेरी का उपयोग कर सकते हैं (अर्थात, प्रोग्रामर के अतिरिक्त किसी अन्य द्वारा लिखित और प्रदान की गई लाइब्रेरी) या सम्भवतः उन्हें अनेक लाइब्रेरी के भागों में निर्माण किया जा सकता है।

जब JVM प्रारंभ किया जाता है, तो तीन क्लास लोडर का उपयोग किया जाता है:[5][6][2]

  1. बूटस्ट्रैप क्लास लोडर
  2. एक्सटेंशन क्लास लोडर
  3. सिस्टम क्लास लोडर

बूटस्ट्रैप क्लास लोडर <JAVA_HOME>/jre/lib (या जावा 9 और उससे ऊपर के लिए <JAVA_HOME>/jmods>) डायरेक्टरी में स्थित कोर जावा लाइब्रेरीज़[fn 1] को लोड करता है। यह क्लास लोडर जो कोर जेवीएम का भाग है, मूल (नेटिव) कोड में लिखा गया है। बूस्ट्रैप ClassLoader किसी क्लासलोडर ऑब्जेक्ट से संबद्ध नहीं है।[2] उदाहरण के लिए, StringBuilder.class.getClassLoader()रिटर्न्स null.[2]

एक्सटेंशन क्लास लोडर एक्सटेंशन डायरेक्टरी (<JAVA_HOME>/jre/lib/ext,[5]या java.ext.dirsसिस्टम प्रॉपर्टी द्वारा निर्दिष्ट किसी अन्य डायरेक्टरी) में कोड लोडिंग करता है।

सिस्टम क्लास लोडर java.class.path पर पाए गए कोड का लोडिंग करता है, जो CLASSPATH एनवायरनमेंट वेरिएबल पर मैप होता है।

यूज़र डिफ़ाइंड क्लास लोडर

जावा क्लास लोडर जावा में लिखा गया है। इसलिए जावा वर्चुअल मशीन की विशेषताओं के ज्ञान के बिना, स्वयं के क्लास लोडर का निर्माण करना संभव है। बूटस्ट्रैप क्लास लोडर के अतिरिक्त प्रत्येक जावा क्लास लोडर में एक पैरेंट क्लास लोडर होता है।[7] पैरेंट क्लास लोडर को उस स्थिति में परिभाषित किया जाता है जब एक नए क्लास लोडर को द्रिश्तान्किक्रित किया जाता है या वर्चुअल मशीन के सिस्टम डिफॉल्ट क्लास लोडर पर स्थित (सेट) किया जाता है।

इससे यह संभव हो जाता है (उदाहरण के लिए):

  • रनटाइम पर क्लासेस को लोड या अनलोड करने के लिए (उदाहरण के लिए HTTP संसाधन से भी रनटाइम पर लाइब्रेरी को गतिशील रूप से लोड करना)। यह इसके लिए एक महत्वपूर्ण विशेषता है:
    • ज्योथन जैसी स्क्रिप्टिंग लैंग्वेज को प्रयुक्त करना
    • JavaBean बिल्डर्स का उपयोग करना
    • यूज़र डिफ़ाइंड एक्सटेंसिबिलिटी की अनुमति देना
    • एक से अधिक नेमस्पेस को सूचनाओं का आदान प्रदान करने की अनुमति देना। उदाहरण के लिए CORBA / RMI प्रोटोकॉल के मूल सिद्धांतों में से एक है।
  • जावा बाइटकोड लोड करने के तरीके को परिवर्तित करने के लिए (उदाहरण के लिए, एन्क्रिप्टेड जावा क्लास बाइटकोड का उपयोग करना संभव है)।[8]
  • लोड किए गए बाइटकोड को संशोधित करने के लिए (उदाहरण के लिए, अस्पेक्ट-ओरिएंटेड प्रोग्रामिंग का उपयोग करते समय अस्पेक्ट की लोड-टाइम व्यूति के लिए)।

जकार्ता ईई में क्लास लोडर

जकार्ता ईई (पूर्व में जावा ईई और जे2ईई) एप्लिकेशन सर्वर सामान्यतः क्लास लोडर के एक ट्री द्वारा परिनियोजित डब्ल्यूएआर (फ़ाइल प्रारूप) या ईएआर (फ़ाइल प्रारूप) संग्रह से क्लासेस लोड करते हैं जो एप्लिकेशन को अन्य अनुप्रयोगों से पृथक करते हैं किन्तु परिनियोजित मॉड्यूल के मध्य क्लासेस साझा करते हैं। तथाकथित सर्वलेट कंटेनर सामान्यतः एक से अधिक क्लास लोडर के संबंध में कार्यान्वित किए जाते हैं।[4][9]

जार हेल

जार हेल डीएलएल हेल के समान एक शब्द है जिसका उपयोग उन सभी विभिन्न प्रकारों का वर्णन करने के लिए किया जाता है जिनमें क्लासलोडिंग प्रक्रिया कार्य नहीं कर सकती है।[10] तीन प्रकार से जार हेल उत्पन्न हो सकता है:

  • किसी सिस्टम पर संस्थापित (इन्सटाल्ड) लाइब्रेरी के दो भिन्न-भिन्न संस्करणों (वर्शन) की आकस्मिक उपस्थिति। इसे सिस्टम द्वारा त्रुटि नहीं माना जाएगा। अपितु, सिस्टम किसी न किसी लाइब्रेरी से क्लासेस लोड करेगा। नई लाइब्रेरी को प्रतिस्थापित करने के स्थान पर उसे उपलब्ध लाइब्रेरी की सूची में संबद्ध करने से हो सकता है कि एप्लिकेशन अभी भी ऐसा व्यवहार कर रहा हो जैसे कि पुरानी लाइब्रेरी उपयोग में है जो कि हो भी सकती है।
  • एक से अधिक लाइब्रेरी या एप्लिकेशन को लाइब्रेरी फू के विभिन्न संस्करणों की आवश्यकता होती है। यदि लाइब्रेरी फू के संस्करण समान क्लास नामों का उपयोग करते हैं तो लाइब्रेरी फू के संस्करणों को उसी क्लास लोडर के साथ लोड करने का कोई अन्य उपाय नहीं है।
  • अत्यधिक जटिल JAR हेल की समस्याएँ उन परिस्थितियों में उत्पन्न होती हैं जो क्लासलोडिंग सिस्टम की पूर्ण जटिलता का लाभ उठाती हैं। एक जावा प्रोग्राम के लिए केवल एक "फ्लैट" क्लास लोडर का उपयोग करना आवश्यक नहीं है, अपितु इसमें अनेक (संभवतः बहुत अधिक) नेस्टेड, सहयोगी क्लास लोडर समाहित हो सकते है। विभिन्न क्लास लोडर द्वारा लोड की गई क्लासेस जटिल प्रकारों से एक दूसरे को प्रभावित कर सकती हैं जो किसी डेवलपर द्वारा पूर्णतया समझ में नहीं आती हैं, जिससे त्रुटियां या बग उत्पन्न होते हैं तथा जिनको एनालाइज, एक्सप्लेन तथा रिसॉल्व करना कठिन होता है।[11]

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

JAR हेल समस्याओं को हल करने के लिए, वर्ष 2005 में एक जावा सामुदायिक प्रक्रिया - JSR 277 प्रारम्भ की गई थी। रिज़ॉल्यूशन - जावा प्लेटफ़ॉर्म मॉड्यूल सिस्टम - का उद्देश्य एक नया वितरण प्रारूप, एक मॉड्यूल संस्करण योजना और एक सामान्य मॉड्यूल रिपॉजिटरी (माइक्रोसॉफ्ट .NET के ग्लोबल असेंबली कैश के उद्देश्य के समान) प्रस्तुत करना है। दिसंबर वर्ष 2008 में सन ने घोषणा की कि JSR 277 को रोक दिया गया है।[12] जावा मॉड्यूल सिस्टम को बाद में "प्रोजेक्ट जिग्सॉ"[13] के रूप में रीबूट किया गया, जिसे जावा 9 में सम्मिलित किया गया था। वर्ष 2017 में विमोचित, इसमें "जावा प्लेटफ़ॉर्म मॉड्यूल सिस्टम" नामक मॉड्यूलर सॉफ़्टवेयर के लिए समर्थन सम्मिलित है जिसे मॉड्यूल-info.java फ़ाइलों के साथ सोर्स लेवल पर नियंत्रित किया जाता है। यह ओएसजीआई आर्किटेक्चर से एक भिन्न सिद्धांत का पालन करता है जिसका उद्देश्य जावा रनटाइम एनवायरनमेंट के लिए बैकवर्ड-कम्पटीएबेल मॉड्यूलरिटी प्रदान करना है जो जेआरई द्वारा प्रदान की जाने वाली लोडिंग क्लासेस के डिफ़ॉल्ट प्रक्रिया का उपयोग करता है। हालाँकि, चूंकि यह विभिन्न संस्करणों के साथ लाइब्रेरीज़ के नियंत्रित सह-उपस्थिति की क्षमता प्रदान नहीं करता है, इसलिए यह JAR हेल की समस्या से निपटने के लिए उपयुक्त नहीं है।[14]

यह भी देखें

फ़ुटनोट

  1. These libraries are stored in Jar files called rt.jar, core.jar, server.jar, etc.

संदर्भ

  1. Mcmanis, Chuck (October 1, 1996). "The basics of Java class loaders". JavaWorld. Retrieved 2020-07-13.
  2. 2.0 2.1 2.2 2.3 Horstmann 2022, §10.1.1 The Class-Loading Process.
  3. Horstmann 2022, §8.2.5 Writing Byte Codes to Memory.
  4. 4.0 4.1 Christudas, Binildas (January 26, 2005). "Internals of Java Class Loading". onjava.com. Archived from the original on 2018-05-10.
  5. 5.0 5.1 "Understanding Extension Class Loading". The Java Tutorials. docs.oracle.com. Retrieved 2020-07-13.
  6. Sosnoski, Dennis (April 29, 2003). "Classes and class loading". IBM DeveloperWorks. Retrieved 2008-01-26.
  7. Horstmann 2022, 10.1.2 The Class Loader Hierarchy.
  8. Roubtsov, Vladimir (May 9, 2003). "Cracking Java byte-code encryption". JavaWorld. Retrieved 2020-07-13.
  9. deBoer, Tim; Karasiuk, Gary (August 21, 2002). "J2EE Class Loading Demystified". IBM DeveloperWorks. Retrieved 2008-01-26.
  10. "Depot - Apache Incubator". Archived from the original on 2013-06-01.
  11. "Taxonomy of class loader problems with Jakarta Commons Logging".
  12. Mark Reinhold (September 20, 2010). "Project Jigsaw". Oracle Corporation. Archived from the original on 2015-12-08.
  13. "Project Jigsaw". Oracle Corporation. Retrieved 2015-11-29.
  14. Bartlett, Neil; Hackbarth, Kai (2016-09-22). "Java 9, OSGi and the Future of Modularity (Part 1)". InfoQ.


बाहरी संबंध