क्यों आरा परियोजना / JPMS?


80

जावा का पैकेज मैनेजमेंट सिस्टम मुझे हमेशा सरल और प्रभावी लगता था। इसका उपयोग JDK द्वारा ही किया जाता है। हम इसका उपयोग नामस्थान और मॉड्यूल की अवधारणा की नकल करने के लिए कर रहे हैं।

क्या है प्रोजेक्ट Jigsaw (उर्फ जावा प्लेटफ़ॉर्म मॉड्यूल सिस्टम ) में भरने की कोशिश कर रहा?

आधिकारिक साइट से:

इस परियोजना का लक्ष्य जावा एसई प्लेटफॉर्म के लिए एक मानक मॉड्यूल प्रणाली को डिजाइन और कार्यान्वित करना है, और उस सिस्टम को स्वयं प्लेटफॉर्म और जेडीके के लिए लागू करना है।

जवाबों:


101

आरा और ओएसजीआई एक ही समस्या को हल करने की कोशिश कर रहे हैं: कैसे अपने आंतरिक परिरक्षण करते समय मोटे अनाज वाले मॉड्यूल को बातचीत करने की अनुमति दें।

आरा के मामले में, मोटे अनाज वाले मॉड्यूल में जावा वर्ग, पैकेज और उनकी निर्भरताएं शामिल हैं।

यहाँ एक उदाहरण है: स्प्रिंग और हाइबरनेट। दोनों के पास 3rd पार्टी JAR CGLIB पर निर्भरता है, लेकिन वे उस JAR के विभिन्न, असंगत संस्करणों का उपयोग करते हैं। यदि आप मानक JDK पर भरोसा करते हैं तो आप क्या कर सकते हैं? उस संस्करण को शामिल करना, जिसमें स्प्रिंग हाइबरनेट और वीज़ा वर्सा को तोड़ना चाहता है।

लेकिन, यदि आपके पास आरा जैसा उच्च-स्तरीय मॉडल है, तो आप आसानी से एक JAR के विभिन्न संस्करणों को विभिन्न मॉड्यूल में प्रबंधित कर सकते हैं। उन्हें उच्च-स्तरीय पैकेज समझें।

यदि आप GitHub स्रोत से स्प्रिंग बनाते हैं तो आप इसे देखेंगे। उन्होंने रूपरेखा को फिर से तैयार किया है, जिसमें कई मॉड्यूल शामिल हैं: कोर, दृढ़ता, आदि। आप मॉड्यूल निर्भरता के न्यूनतम सेट को चुन सकते हैं और चुन सकते हैं जो आपके आवेदन की आवश्यकता है और बाकी को अनदेखा करें। यह एक सिंगल स्प्रिंग JAR हुआ करता था, जिसमें सभी .class फाइलें थीं।

अद्यतन: पांच साल बाद - आरा में अभी भी कुछ मुद्दे हल हो सकते हैं।


5
क्या होगा यदि आपको अभी भी उसी समान मॉड्यूल का उपयोग करने की आवश्यकता है, लेकिन इसके दो अलग-अलग संस्करण? क्या उन्हें किसी तरह का समर्थन नहीं देना चाहिए ताकि एक ही वर्ग के दो संस्करण सह-अस्तित्व में आ सकें?
डिडियर ए।

7
यह पोस्ट भ्रामक है जिसे वास्तव में जावा 9 में जारी किया गया है। यह लेखन के समय सटीक हो सकता है।
xenoterracide

1
mreinhold.org/blog/jư-complete प्रोजेक्ट पूरा हुआ और जावा 9 के लिए जारी किया गया
ज़सज़

@xenoterracide, आप क्लैरवॉयंट नहीं होने के लिए किसी को दोष नहीं दे सकते। इस पोस्ट ने जावा 9 को पांच साल से पहले छोड़ दिया। क्या आप जॉन स्कीट के हर उत्तर की समीक्षा कर रहे हैं?
duffymo

इस पद की उम्र अच्छी नहीं थी। जावा मॉड्यूल जानबूझकर संस्करण की समस्या को हल नहीं करते हैं, इस धागे को देखें । अभी भी हमारे पुराने दोस्तों के आसपास जाने का कोई आसान तरीका नहीं है NoSuchMethodErrorऔर NoClassDefFoundError
तमसा हेगड़ेस

45

AFAIK JRE को अधिक मॉड्यूलर बनाने की योजना है। यानी छोटे जार हैं जो वैकल्पिक हैं और / या आप केवल उसी कार्यक्षमता को डाउनलोड / अपग्रेड कर सकते हैं जिसकी आपको आवश्यकता है।

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


7
स्वीकृत उत्तर मान्य है, लेकिन यह उत्तर बेहतर है क्योंकि यह वास्तविक वांछित प्रभावों की व्याख्या करता है। +1, अच्छी तरह से योग्य है।
सिल्वियु बर्किया

मैं उत्सुक हूं इसलिए इसका मतलब यह भी है कि अगर मेरे पास Google अमरूद एक निर्भरता के रूप में है, लेकिन मैं केवल इसमें ImmutableList का उपयोग करता हूं, तो मैं केवल ImmutableList निर्भरता को आयात कर सकता हूं और शेष अमरूद कक्षाओं को छोड़ सकता हूं?
tmn

1
@ThomasN जब आप importयह सब करते हैं, तो इस वर्ग को संकलक के लिए कक्षा के नाम स्थान में लाया जाता है। यदि आप वास्तव में इसका उपयोग नहीं करते हैं, तो यह बनाए गए बाइट कोड में दिखाई नहीं देगा। यदि आप वास्तव में कक्षा का उपयोग करते हैं, तो आपको उस वर्ग और प्रत्येक वर्ग के लिए रनटाइम का उपयोग करना होगा। सिद्धांत रूप में आप अमरूद एपीआई का एक कट डाउन संस्करण बना सकते हैं, जिसमें आपको केवल वही चाहिए जो इसके बदले आपको चाहिए और उस जार का उपयोग करें। वास्तव में, यह त्रुटि प्रवण है और अधिकांश मामलों में बहुत उपयोगी नहीं है, और आप अंत में जारी किए गए अनुसार पूरे जार को जोड़ते हैं।
पीटर लॉरी

43

डेक्सॉक्स बेल्जियम में मार्क रेनहोल्ड के मुख्य भाषण के आधार पर , प्रोजेक्ट आरा दो मुख्य दर्द बिंदुओं को संबोधित करने जा रहा है:

  1. क्लासपाथ
  2. बड़े पैमाने पर अखंड JDK

क्लासपाथ में क्या गड़बड़ है?

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

  • यह बताना मुश्किल है कि क्या संघर्ष हैं। मावेन जैसे उपकरण कलाकृतियों के नाम के आधार पर बहुत अच्छा काम कर सकते हैं, लेकिन अगर कलाकृतियों के अलग-अलग नाम हैं, लेकिन एक ही सामग्री है, तो संघर्ष हो सकता है।
  • जार फ़ाइलों के साथ मूलभूत समस्या यह है कि वे घटक नहीं हैं। वे फ़ाइल कंटेनरों का सिर्फ एक गुच्छा हैं जिन्हें रैखिक रूप से खोजा जाएगा। क्लासपैथ कक्षाओं को देखने का एक तरीका है, चाहे वे किसी भी घटक में हों, वे किस पैकेज में हैं या उनके इच्छित उपयोग में हैं।

बड़े पैमाने पर अखंड JDK

JDK की बड़ी अखंड प्रकृति कई समस्याओं का कारण बनती है:

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

मॉड्यूल: आम समाधान

उपरोक्त समस्याओं को दूर करने के लिए, हम मॉड्यूल को मौलिक नई तरह के जावा प्रोग्राम घटक के रूप में मानते हैं। एक मॉड्यूल कोड और डेटा का एक नाम, आत्म-वर्णन संग्रह है। इसका कोड संकुल के एक प्रकार के रूप में आयोजित किया जाता है, अर्थात, जावा वर्ग और इंटरफेस; इसके डेटा में संसाधन और अन्य प्रकार की स्थिर जानकारी शामिल है।

यह नियंत्रित करने के लिए कि इसका कोड अन्य मॉड्यूल के प्रकारों को कैसे संदर्भित करता है, एक मॉड्यूल घोषित करता है कि किन अन्य मॉड्यूलों को संकलित करने और चलाने के लिए इसकी आवश्यकता है। यह नियंत्रित करने के लिए कि अन्य मॉड्यूल में कोड अपने पैकेजों के प्रकारों को कैसे संदर्भित करता है, एक मॉड्यूल घोषित करता है कि वह उन पैकेजों में से कौन सा निर्यात करता है।

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

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

JEP का अनुसरण करें

आरा एक बहुत बड़ा प्रोजेक्ट है जो काफी सालों से चल रहा है। इसे JEP की प्रभावशाली राशि मिली है जो परियोजना के बारे में अधिक जानकारी प्राप्त करने के लिए शानदार स्थान हैं। इनमें से कुछ JEP निम्नलिखित हैं:

  • JEP 200: मॉड्यूलर JDK : JDK को संशोधित करने के लिए जावा प्लेटफॉर्म मॉड्यूल सिस्टम (JPMS) का उपयोग करें
  • JEP 201: मॉड्यूलर स्रोत कोड : मॉड्यूल में JDK स्रोत कोड को पुनर्गठित करें, मॉड्यूल को संकलित करने के लिए बिल्ड सिस्टम बढ़ाएं, और बिल्ड समय पर मॉड्यूल सीमाओं को लागू करें
  • JEP 261: मॉड्यूल सिस्टम : जावा प्लेटफॉर्म मॉड्यूल सिस्टम को लागू करें, जैसा कि JSR 376 द्वारा निर्दिष्ट किया गया है, साथ में संबंधित JDK- विशिष्ट परिवर्तन और संवर्द्धन।
  • JEP 220: मॉड्यूलर रन-टाइम छवियां : मॉड्यूल को समायोजित करने और प्रदर्शन, सुरक्षा और रखरखाव को बेहतर बनाने के लिए JDK और JRE रन-टाइम छवियों को पुनर्स्थापित करें।
  • JEP 260: अधिकांश आंतरिक API को एन्क्रिप्ट करें : JDK के अधिकांश आंतरिक API को डिफ़ॉल्ट रूप से अप्राप्य बनाते हैं, लेकिन कुछ महत्वपूर्ण, व्यापक रूप से उपयोग किए जाने वाले आंतरिक API को तब तक छोड़ देते हैं, जब तक समर्थित प्रतिस्थापन सभी या उनकी अधिकांश कार्यक्षमता के लिए मौजूद न हों।
  • JEP 282: jlink: जावा लिंकर : एक उपकरण बनाएं जो मॉड्यूल और उनकी निर्भरता के एक सेट को कस्टम रन-टाइम इमेज में एक कस्टम रन-टाइम इमेज के रूप में इकट्ठा और ऑप्टिमाइज़ कर सके। JEP 220

अंतिम शब्द

द स्टेट ऑफ़ द मॉड्यूल सिस्टम रिपोर्ट के प्रारंभिक संस्करण में , मार्क रीनहोल्ड ने मॉड्यूल सिस्टम के विशिष्ट लक्ष्यों का वर्णन निम्नानुसार किया है:

  • विश्वसनीय विन्यास , कार्यक्रम घटकों के लिए एक साधन के साथ भंगुर, त्रुटि-प्रवण वर्ग-पथ तंत्र को बदलने के लिए, एक दूसरे पर स्पष्ट निर्भरता घोषित करने के लिए
  • मजबूत एनकैप्सुलेशन , एक घटक को यह घोषित करने की अनुमति देने के लिए कि उसके कौन से सार्वजनिक प्रकार अन्य घटकों के लिए सुलभ हैं, और जो नहीं हैं।

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


3
मार्क रीनहोल्ड ओरेकल में जावा प्लेटफ़ॉर्म ग्रुप के मुख्य वास्तुकार हैं, और यह उत्तर मूल रूप से उस सटीक प्रश्न का सीधा उत्तर है।
Jay

1
आपको सूचित करने के लिए कि, हैलोवर्ल्ड 553 एमबी के बजाय 15 एमबी का उपयोग कर सकता है; youtu.be/rFhLXcOBsk?t=31m12s
user1133275

14

तर्क के लिए, आइए दावा करते हैं कि जावा 8 (और पहले) में पहले से ही मॉड्यूल (जार) और मॉड्यूल सिस्टम (क्लासपाथ) का "फॉर्म" है। लेकिन इन के साथ अच्छी तरह से ज्ञात समस्याएं हैं।

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

समस्या 1: सार्वजनिक भी सार्वजनिक है

निम्नलिखित वर्गों पर विचार करें (मान लें कि दोनों सार्वजनिक हैं):

com.acme.foo.db.api.UserDao
com.acme.foo.db.impl.UserDaoImpl

Foo.com पर, हम यह तय कर सकते हैं कि हमारी टीम को उपयोग करना चाहिए UserDaoऔर उपयोग नहीं करना चाहिएUserDaoImpl सीधे । हालाँकि, क्लासपाथ पर इसे लागू करने का कोई तरीका नहीं है।

आरा में, एक मॉड्यूल में एक module-info.javaफ़ाइल होती है जो हमें स्पष्ट रूप से यह बताने की अनुमति देती है कि अन्य मॉड्यूल के लिए सार्वजनिक क्या है। अर्थात्, जनता के पास बारीकियों है। उदाहरण के लिए:

// com.acme.foo.db.api.UserDao is accessible, but
// com.acme.foo.db.impl.UserDaoImpl is not 
module com.acme.foo.db {
    exports com.acme.foo.db.api;
}

समस्या 2: प्रतिबिंब बेलगाम है

# 1 में कक्षाओं को देखते हुए, कोई भी अभी भी जावा 8 में ऐसा कर सकता है:

Class c = Class.forName("com.acme.foo.db.impl.UserDaoImpl");
Object obj = c.getConstructor().newInstance();

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

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

समस्या 3: क्लासपाथ वास्तु संबंधों को मिटा देता है

एक टीम में आम तौर पर जार के बीच संबंधों के बारे में एक मानसिक मॉडल होता है। उदाहरण के लिए, foo-app.jarउपयोग हो सकता है foo-services.jarजो उपयोग करता है foo-db.jar। हम foo-app.jar"सर्विस लेयर" को बायपास नहीं करना चाहिए और foo-db.jarसीधे उपयोग करना चाहिए । हालांकि, क्लासपैथ के माध्यम से इसे लागू करने का कोई तरीका नहीं है। मार्क रीनहोल्ड ने यहां इसका उल्लेख किया है

तुलना करके, आरा मॉड्यूल के लिए एक स्पष्ट, विश्वसनीय पहुंच मॉडल प्रदान करता है।

समस्या 4: अखंड रन-टाइम

जावा रनटाइम अखंड में है rt.jar। मेरी मशीन पर, 20k वर्गों के साथ यह 60+ एमबी है! सूक्ष्म सेवाओं, IoT उपकरणों, आदि के युग में, यदि उनका उपयोग नहीं किया जा रहा है, तो डिस्क पर कोरबा, स्विंग, एक्सएमएल और अन्य पुस्तकालयों का होना अवांछनीय है।

आरा कई मॉड्यूल में जेडीके को ही तोड़ता है ; उदाहरण के लिए java.sql में परिचित SQL कक्षाएं हैं। इसके कई लाभ हैं, लेकिन एक नया jlinkउपकरण है। एक ऐप को पूरी तरह से संशोधित माना जाता है, jlinkएक वितरण योग्य रन-टाइम छवि उत्पन्न करता है जिसे केवल निर्दिष्ट मॉड्यूल (और उनकी निर्भरता) को शामिल करने के लिए छंटनी की जाती है। आगे की ओर देखते हुए, ओरेकल भविष्य को आगे बढ़ाता है जहां जेडडीके मॉड्यूल को मूल कोड में आगे-आगे संकलित किया जाता है। हालांकि jlinkवैकल्पिक है, और एओटी संकलन प्रयोगात्मक है, वे प्रमुख संकेत हैं जहां ओरेकल का नेतृत्व किया जाता है।

समस्या 5: संस्करण

यह सर्वविदित है कि क्लासपैथ हमें एक ही जार के कई संस्करणों का उपयोग करने की अनुमति नहीं देता है: जैसे bar-lib-1.1.jarऔर bar-lib-2.2.jar

आरा इस समस्या को संबोधित नहीं करता है; मार्क रीनहोल्ड ने यहां तर्क दिया है । सार यह है कि मावेन, ग्रैडल और अन्य उपकरण निर्भरता प्रबंधन के लिए एक बड़े पारिस्थितिकी तंत्र का प्रतिनिधित्व करते हैं, और एक अन्य समाधान लाभकारी से अधिक हानिकारक होगा।

यह ध्यान दिया जाना चाहिए कि अन्य समाधान (जैसे OSGi) वास्तव में इस समस्या को संबोधित करते हैं (और अन्य, # 4 से अलग)।

जमीनी स्तर

आरा के लिए कुछ प्रमुख बिंदु, विशिष्ट समस्याओं से प्रेरित हैं।

ध्यान दें कि आरा, OSGi, JBoss मॉड्यूल, आदि के बीच विवाद की व्याख्या एक अलग चर्चा है जो किसी अन्य स्टैन एक्सचेंज साइट पर है। यहाँ वर्णित की तुलना में समाधानों के बीच कई और अंतर हैं। क्या अधिक है, JSR 376 के लिए सार्वजनिक समीक्षा पुनर्विचार मतदान को अनुमोदित करने के लिए पर्याप्त सहमति थी ।


3

यह आलेख उन समस्याओं के बारे में विस्तार से बताता है, जो OSGi और JPMS / आरा दोनों को हल करने की कोशिश करते हैं:

"जावा 9, ओएसजीआई एंड द फ्यूचर ऑफ मॉड्युलरिटी" [22 एसईपी 2016]

यह OSGi और JPMS / आरा दोनों के दृष्टिकोण में पूरी तरह से चला जाता है। अब तक, यह प्रकट होता है कि लेखक परिपक्व (16 वर्ष) के ओएसजीआई की तुलना में जेपीएमएस / आरा के लिए लगभग कोई व्यावहारिक पेशेवरों को सूचीबद्ध नहीं करते हैं।

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