डिपेंडेंसी मैनेजमेंट

किसी समस्या की शिकायत करें सोर्स देखें Nightly · 7.4 . 7.3 · 7.2 · 7.1 · 7.0 · 6.5

पिछले पेजों को देखते समय, एक थीम बार-बार दिखती है: अपने कोड को मैनेज करना काफ़ी आसान है, लेकिन उसकी डिपेंडेंसी को मैनेज करना काफ़ी मुश्किल है. ये सभी चीज़ें निर्भर करती हैं: कभी-कभी किसी टास्क पर निर्भर हो. जैसे, “मैं रिलीज़ को इस रूप में मार्क करने से पहले दस्तावेज़ को पुश करना चाहता हूं पूरा) दिखता है, और कभी-कभी आर्टफ़ैक्ट पर निर्भरता होती है (जैसे कि “मुझे यह करना है” मेरे पास कोड बनाने के लिए, कंप्यूटर विज़न लाइब्रेरी का सबसे नया वर्शन होना चाहिए"). कभी-कभी, आपकी कोड बेस के दूसरे हिस्से पर इंटरनल डिपेंडेंसी होती हैं और कभी-कभी आपकी कंपनी अन्य टीम के मालिकाना हक वाले कोड या डेटा पर निर्भर करती है (या तो आपके संगठन में या किसी तीसरे पक्ष में). हालांकि, किसी भी मामले में, “मैं की ज़रूरत होती है, यह बात बार-बार आती रहती है और डिपेंडेंसी मैनेज करना, शायद दुनिया भर में बुनियादी काम है.

मॉड्यूल और डिपेंडेंसी चुनना

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

फ़ाइन-ग्रैन्ड मॉड्यूल और 1:1:1 नियम का इस्तेमाल करना

आर्टफ़ैक्ट पर आधारित बिल्ड को तैयार करते समय सबसे ज़रूरी सवाल यह होता है कि यह तय किया जा सकता है कि किसी मॉड्यूल में कितनी सुविधाएं होनी चाहिए. Basel में, मॉड्यूल को टारगेट करके दिखाया जाता है. इसमें ऐसी बनाने लायक यूनिट तय की जाती है java_library या go_binary. एक तरफ़, पूरे प्रोजेक्ट को एक ही मॉड्यूल में रखा जा सकता है. इसके लिए, रूट में एक BUILD फ़ाइल डालें और उस प्रोजेक्ट की सभी सोर्स फ़ाइलों को बार-बार ग्लोब करें. दूसरे पर एक्सट्रीम, करीब हर सोर्स फ़ाइल को असरदार तरीके से इसके खुद के मॉड्यूल में बनाया जा सकता है हर फ़ाइल को BUILD फ़ाइल में शामिल करने के लिए, हर दूसरी फ़ाइल पर निर्भर करता है.

ज़्यादातर प्रोजेक्ट, इन सीमाओं के बीच होते हैं और फ़ैसला लेने के लिए परफ़ॉर्मेंस और रखरखाव के बीच संतुलन बनाना. एक मॉड्यूल का उपयोग करके पूरे प्रोजेक्ट का मतलब यह हो सकता है कि आपको इसे छोड़कर BUILD फ़ाइल को छूना न पड़े बाहरी डिपेंडेंसी जोड़ते समय, इसका मतलब है कि बिल्ड सिस्टम को पूरे प्रोजेक्ट को हमेशा एक साथ बनाएं. इसका मतलब है कि यह, बिल्ड के हिस्सों को एक साथ प्रोसेस नहीं कर पाएगा या उन्हें डिस्ट्रिब्यूट नहीं कर पाएगा. साथ ही, यह उन हिस्सों को कैश मेमोरी में सेव नहीं कर पाएगा जिन्हें पहले ही बनाया जा चुका है. हर फ़ाइल में एक मॉड्यूल का विकल्प इसके उलट है: बिल्ड सिस्टम के पास, बिल्ड के चरणों को कैश मेमोरी में सेव करने और शेड्यूल करने में ज़्यादा सुविधाएं होती हैं. हालांकि, जब भी इंजीनियर यह बदलते हैं कि कौनसी फ़ाइलें किसका रेफ़रंस देती हैं, तो उन्हें डिपेंडेंसी की सूचियों को मैनेज करने में ज़्यादा मेहनत करनी पड़ती है.

हालांकि, जानकारी का सटीक ब्यौरा, भाषा के हिसाब से अलग-अलग होता है. आम तौर पर, है), तो Google किसी एक मॉड्यूल की तुलना में काफ़ी छोटे मॉड्यूल को पसंद करता है आम तौर पर, टास्क पर आधारित बिल्ड सिस्टम में लिखा जाता है. Google पर आम तौर पर, प्रोडक्शन के लिए बनाई गई बाइनरी, अक्सर हज़ारों टारगेट पर निर्भर करती है. यहां तक कि एक सामान्य टीम के पास भी अपने कोडबेस में कई सौ टारगेट हो सकते हैं. इन भाषाओं के लिए ऐसा Java जिसमें पैकेजिंग का बेहतरीन अनुभव मिलता है, हर डायरेक्ट्री आम तौर पर इसमें एक पैकेज, टारगेट, और BUILD फ़ाइल (पैंट, दूसरा बिल्ड सिस्टम) मौजूद है बेज़ल के आधार पर, इसे 1:1:1 नियम कहते हैं). कमज़ोर पैकेजिंग वाली भाषाएं कन्वेंशन अक्सर हर BUILD फ़ाइल में कई टारगेट तय करते हैं.

छोटे बिल्ड टारगेट के फ़ायदे बड़े पैमाने पर दिखने लगते हैं, क्योंकि इससे बिल्ड ज़्यादा तेज़ी से डिस्ट्रिब्यूट किए जाते हैं और टारगेट फिर से बनाने की ज़रूरत कम पड़ती है. टेस्टिंग के बाद, ये फ़ायदे और भी ज़्यादा असरदार हो जाते हैं. ऐसा इसलिए, क्योंकि बेहतर टारगेट का मतलब है कि बिल्ड सिस्टम, टेस्ट के सिर्फ़ उस सीमित सबसेट को चलाने के बारे में ज़्यादा बेहतर तरीके से तय कर सकता है जिस पर किसी भी बदलाव का असर पड़ सकता है. Google, छोटे टारगेट का इस्तेमाल करने के सिस्टम के फ़ायदों में विश्वास करता है. इसलिए, हमने BUILD फ़ाइलों को अपने-आप मैनेज करने के लिए टूल बनाने में निवेश किया है, ताकि डेवलपर पर बोझ न पड़े. इससे, इस समस्या को कम करने में मदद मिली है.

इनमें से कुछ टूल, जैसे कि buildifier और buildozer, buildtools डायरेक्ट्री में Bazel के साथ उपलब्ध हैं.

मॉड्यूल दिखने की संभावना कम करना

Bazel और अन्य बिल्ड सिस्टम, हर टारगेट के लिए एक विज़िबिलिटी तय करने की अनुमति देते हैं. यह एक ऐसी प्रॉपर्टी है जिससे यह तय होता है कि कौनसे अन्य टारगेट उस पर निर्भर हो सकते हैं. निजी टारगेट का संदर्भ सिर्फ़ उसकी BUILD फ़ाइल में दिया जा सकता है. कोई टारगेट, BUILD फ़ाइलों की साफ़ तौर पर तय की गई सूची के टारगेट को ज़्यादा लोगों को दिखा सकता है. इसके अलावा, सार्वजनिक तौर पर दिखने की स्थिति में, Workspace के हर टारगेट को दिखाया जा सकता है.

ज़्यादातर प्रोग्रामिंग भाषाओं की तरह, 'किसको दिखे' सेटिंग को आम तौर पर जितना संभव हो सके. आम तौर पर, Google की टीमें टारगेट को सिर्फ़ तब सार्वजनिक करती हैं, जब वे टारगेट, Google की किसी भी टीम के लिए उपलब्ध लाइब्रेरी के बारे में बताते हैं. ये लाइब्रेरी बड़े पैमाने पर इस्तेमाल की जाती हैं. जिन टीमों को अपने कोड का इस्तेमाल करने से पहले दूसरों के साथ मिलकर काम करना होता है वे ये काम करेंगी टारगेट की विज़िबिलिटी के तौर पर, उन लोगों या संगठनों की सूची को बनाए रखना जिन्हें अनुमति मिली हुई है. हर टीम के लागू करने के लिए तय किए गए टारगेट, सिर्फ़ उन डायरेक्ट्री तक सीमित होंगे जिनका मालिकाना हक टीम के पास है. साथ ही, ज़्यादातर BUILD फ़ाइलों का सिर्फ़ एक टारगेट ऐसा होगा जो निजी नहीं होगा.

डिपेंडेंसी मैनेज करना

मॉड्यूल ऐसा होना चाहिए कि वे एक-दूसरे को रेफ़र कर सकें. कोडबेस को छोटे-छोटे मॉड्यूल में बांटने का नुकसान यह है कि आपको उन मॉड्यूल के बीच डिपेंडेंसी मैनेज करनी पड़ती है. हालांकि, टूल की मदद से इसे ऑटोमेट किया जा सकता है. इन्हें ज़ाहिर करना आम तौर पर, डिपेंडेंसी BUILD फ़ाइल में मौजूद कॉन्टेंट का ज़्यादातर हिस्सा होती है.

इंटरनल डिपेंडेंसी

किसी बड़े प्रोजेक्ट को छोटे-छोटे मॉड्यूल में बांटने पर, ज़्यादातर डिपेंडेंसी इंटरनल हो सकती हैं. इसका मतलब है कि वे उसी सोर्स रिपॉज़िटरी में तय किए गए और बनाए गए किसी दूसरे टारगेट पर होंगी. इंटरनल डिपेंडेंसी, बाहरी डिपेंडेंसी से इस मामले में अलग होती हैं कि इन्हें सोर्स से बनाया जाता है, न कि बिल्ड करते समय पहले से बने आर्टफ़ैक्ट के तौर पर डाउनलोड किया जाता है. इसका मतलब यह भी है कि ऐसी किसी रणनीति के लिए “वर्शन” इंटरनल डिपेंडेंसी—टारगेट और उसकी सभी इंटरनल डिपेंडेंसी हमेशा डेटा स्टोर करने की जगह में उसी कमिट/रिविज़न के साथ बनाया जाता है. एक समस्या जो यह होनी चाहिए कि यह समझना ज़रूरी है कि आंतरिक डिपेंडेंसी का ध्यान रखते हुए कैसे काम किया जाए ट्रांज़िटिव डिपेंडेंसी (इमेज 1). मान लें कि टारगेट A, टारगेट B पर निर्भर करता है, जो एक सामान्य लाइब्रेरी टारगेट C पर निर्भर करता है. क्या A को लक्षित करता है, जो क्लास का इस्तेमाल करने में सक्षम है टारगेट C में तय किया गया है?

ट्रांज़िटिव डिपेंडेंसी

पहली इमेज. ट्रांसीटिव डिपेंडेंसी

जहां तक बुनियादी टूल का सवाल है, इसमें कोई समस्या नहीं है; दोनों टारगेट A के बनने पर B और C को टारगेट A में जोड़ा जाएगा, इसलिए इनमें से कोई भी सिंबल C को A के तौर पर जाना जाता है. बेज़ल ने कई सालों तक इसकी मंज़ूरी दी, लेकिन जैसे-जैसे Google ने तरक्की की, हम में समस्याएं दिखने लगीं. मान लें कि B को इस तरह रीफ़ैक्ट किया गया था कि अब वह C पर निर्भर रहने की ज़रूरत थी. अगर B की C पर निर्भरता हटा दी जाती है, तो A और B पर निर्भरता के ज़रिए C का इस्तेमाल करने वाला कोई भी दूसरा टारगेट काम नहीं करेगा. असल में, किसी टारगेट की डिपेंडेंसी, उसके सार्वजनिक कॉन्ट्रैक्ट का हिस्सा बन गईं और उन्हें कभी भी सुरक्षित तरीके से बदला नहीं जा सका. इसका मतलब है कि समय के साथ डिपेंडेंसी इकट्ठा होती है और Google धीमा होना शुरू हो गया है.

Google ने इस समस्या को हल करने के लिए, “स्ट्रिक्ट ट्रांज़िटिव” इस्तेमाल किया डिपेंडेंसी मोड” पर सेट करना होगा. इस मोड में, Basel को पता चलता है कि टारगेट सीधे निर्भर किए बिना किसी प्रतीक का संदर्भ देता है और, यदि है, तो इसके साथ विफल होता है और एक शेल कमांड का उपयोग किया जा सकता है, जिसका उपयोग निर्भर है. Google के पूरे कोडबेस में इस बदलाव को रोल आउट करने और लाखों बिल्ड टारगेट में से हर एक को फिर से बनाने में कई साल लग गए. ऐसा इसलिए किया गया, ताकि उनकी डिपेंडेंसी की साफ़ तौर पर सूची बनाई जा सके. हालांकि, यह बदलाव करना ज़रूरी था. हमारे बिल्ड हैं अब पहले से ज़्यादा तेज़ी से होने की वजह से, टारगेट पर ग़ैर-ज़रूरी चीज़ें कम हो गई हैं और इंजीनियर को बिना किसी चिंता के ऐसी चीज़ें हटाने की ताकत मिलती है जिनकी उन्हें ज़रूरत नहीं है जो उन टारगेट पर निर्भर हैं.

हमेशा की तरह, सख्त ट्रांज़िटिव डिपेंडेंसी लागू करने के दौरान ट्रेड-ऑफ़ हुआ. इसने बनाया ज़्यादा जानकारी वाली फ़ाइलें बनाने की ज़रूरत होती है, क्योंकि अक्सर इस्तेमाल की जाने वाली लाइब्रेरी को अब सूची में जोड़ने की ज़रूरत होती है कई जगहों पर हो सकता है, जबकि अचानक ऐसा नहीं हो सकता, लेकिन इंजीनियर BUILD फ़ाइलों में डिपेंडेंसी जोड़ने में ज़्यादा मेहनत करनी पड़ी. हम तब से लेकर अब तक हमने ऐसे टूल बनाए हैं जो किसी समस्या का पता लगाकर, उसे कम करने में मदद करते हैं. डिपेंडेंसी और उन्हें बिना किसी डेवलपर के, BUILD फ़ाइलों में जोड़ना मदद की जा सकती है. हालांकि, कोडबेस के स्केल होने पर, हमें लगता है कि ऐसे टूल के बिना भी, यह बदलाव करना सही है: BUILD फ़ाइल में साफ़ तौर पर डिपेंडेंसी जोड़ने पर, एक बार शुल्क देना पड़ता है. हालांकि, जब तक बिल्ड टारगेट मौजूद है, तब तक इनपुट के तौर पर इस्तेमाल होने वाली डिपेंडेंसी से जुड़ी समस्याएं बनी रह सकती हैं. बेज़ल स्ट्रिक ट्रांज़िटिव डिपेंडेंसी लागू करता है डिफ़ॉल्ट रूप से Java कोड पर सेट करें.

बाहरी डिपेंडेंसी

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

डिपेंडेंसी को अपने-आप मैनेज करने की सुविधा बनाम मैन्युअल तरीके से मैनेज करना

बिल्ड सिस्टम की मदद से, बाहरी डिपेंडेंसी के वर्शन को मैन्युअल या अपने-आप मैनेज किया जा सकता है. मैन्युअल रूप से मैनेज किए जाने पर, बिल्डफ़ाइल आर्टफ़ैक्ट डेटा स्टोर करने की जगह से वह वर्शन साफ़ तौर पर डाउनलोड करता है जिसे वह डाउनलोड करना चाहता है, अक्सर सिमेंटिक वर्शन स्ट्रिंग का इस्तेमाल किया जाता है, जैसे कि 1.1.4 के तौर पर. अपने-आप मैनेज होने पर, सोर्स फ़ाइल की अनुमति है और बिल्ड सिस्टम हमेशा सबसे नया वर्शन डाउनलोड करता है. उदाहरण के लिए, Gradle की मदद से डिपेंडेंसी के वर्शन को “1.+” के तौर पर दिखाया जा सकता है. इससे यह पता चलता है कि डिपेंडेंसी का कोई भी मामूली या पैच वर्शन स्वीकार किया जा सकता है, बशर्ते उसका मुख्य वर्शन 1 हो.

अपने-आप मैनेज होने वाली डिपेंडेंसी, छोटे प्रोजेक्ट के लिए आसान हो सकती हैं. हालांकि, आम तौर पर, छोटी-छोटी चीज़ों के बड़े साइज़ वाले प्रोजेक्ट की आपदा की रेसिपी है या जिस पर एक से ज़्यादा इंजीनियर काम कर रहे हैं. अपने-आप होने वाली समस्या मैनेज की जा रही डिपेंडेंसी यह है कि अपडेट किया गया. यह गारंटी देने का कोई तरीका नहीं है कि बाहरी पक्ष अपडेट (भले ही वे सिमैंटिक वर्शन के इस्तेमाल का दावा करें), इसलिए एक ऐसा बिल्ड क्या काम करती है, लेकिन अगले दिन काम करना बंद कर सकता है. साथ ही, यह पता करने का कोई आसान तरीक़ा नहीं है कि क्या बदलाव हुए हैं या उसे काम की स्थिति में वापस लाएं. भले ही, बिल्ड में कोई गड़बड़ी न हो, लेकिन व्यवहार या परफ़ॉर्मेंस में ऐसे बदलाव हो सकते हैं जिन्हें ट्रैक करना मुश्किल हो.

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

एक वर्शन का नियम

आम तौर पर, किसी लाइब्रेरी के अलग-अलग वर्शन को अलग-अलग आर्टफ़ैक्ट से दिखाया जाता है. इसलिए, सिद्धांत रूप से, किसी बाहरी डिपेंडेंसी के अलग-अलग वर्शन को बिल्ड सिस्टम में अलग-अलग नामों से एलान नहीं किया जा सकता. इस तरह, हर टारगेट यह चुन सकता है कि वह डिपेंडेंसी का कौनसा वर्शन चाहता है इस्तेमाल करें. इससे, काम करने में कई समस्याएं आती हैं. इसलिए, Google अपने कोडबेस में तीसरे पक्ष की सभी डिपेंडेंसी के लिए, एक वर्शन का नियम लागू करता है.

एक से ज़्यादा वर्शन इस्तेमाल करने की अनुमति देने से जुड़ी सबसे बड़ी समस्या, डायमंड डिपेंडेंसी से जुड़ी समस्या है. मान लें कि टारगेट A, टारगेट B और किसी बाहरी लाइब्रेरी के v1 पर निर्भर करता है. अगर टारगेट B को बाद में इसी के v2 पर डिपेंडेंसी जोड़ने के लिए रीफ़ैक्ट किया जाता है बाहरी लाइब्रेरी, लक्ष्य A ब्रेक होगा, क्योंकि अब यह स्पष्ट रूप से दो पर निर्भर है एक ही लाइब्रेरी के अलग-अलग वर्शन हैं. असल में, किसी टारगेट से कई वर्शन वाली तीसरे पक्ष की लाइब्रेरी में नई डिपेंडेंसी जोड़ना कभी भी सुरक्षित नहीं होता. ऐसा इसलिए, क्योंकि टारगेट के किसी भी उपयोगकर्ता का इस्तेमाल पहले से ही किसी दूसरे वर्शन पर हो सकता है. एक वर्शन वाले नियम का पालन करने से यह टकराव नामुमकिन हो जाता है—अगर टारगेट, किसी तीसरे पक्ष की लाइब्रेरी, किसी भी मौजूदा डिपेंडेंसी पर डिपेंडेंसी जोड़ता है पहले से ही उसी वर्शन पर हो जाएगा, ताकि वे साथ-साथ रह सकें.

ट्रांसिटिव बाहरी डिपेंडेंसी

किसी बाहरी डिपेंडेंसी की ट्रांज़िशन डिपेंडेंसी से निपटना खास तौर पर मुश्किल हो सकता है. Maven सेंट्रल जैसे कई आर्टफ़ैक्ट डेटा स्टोर करने की जगहों पर, में अन्य आर्टफ़ैक्ट के खास वर्शन की ज़रूरत के हिसाब से आर्टफ़ैक्ट डेटा स्टोर करने की जगह. Maven या Gradle जैसे टूल बनाएं. इन्हें अक्सर बार-बार डाउनलोड किया जाता है डिफ़ॉल्ट रूप से ट्रांज़िटिव डिपेंडेंसी. इसका मतलब है कि एक डिपेंडेंसी जोड़ने पर, आपके प्रोजेक्ट की वजह से कई आर्टफ़ैक्ट डाउनलोड हो सकते हैं कुल.

यह बहुत सुविधाजनक है: किसी नई लाइब्रेरी पर डिपेंडेंसी जोड़ते समय, उस लाइब्रेरी की सभी ट्रांज़िशन डिपेंडेंसी को ट्रैक करना और उन्हें मैन्युअल तरीके से जोड़ना बहुत मुश्किल होता है. हालांकि, इसका एक बड़ा नुकसान भी है: अलग-अलग लाइब्रेरी, तीसरे पक्ष की एक ही लाइब्रेरी के अलग-अलग वर्शन पर निर्भर हो सकती हैं. इसलिए, यह रणनीति 'एक वर्शन' नियम का उल्लंघन करती है और डायमंड डिपेंडेंसी की समस्या पैदा करती है. अगर आपका टारगेट, दो बाहरी लाइब्रेरी पर निर्भर करता है, जो एक ही डिपेंडेंसी के अलग-अलग वर्शन का इस्तेमाल करती हैं, तो यह नहीं बताया जा सकता कि आपको कौनसा वर्शन मिलेगा. इसका यह भी मतलब है कि किसी बाहरी डिपेंडेंसी को अपडेट करने पर, पूरे कोडबेस में गड़बड़ियां हो सकती हैं. ऐसा तब होता है, जब नया वर्शन अपनी कुछ डिपेंडेंसी के ऐसे वर्शन को इंपोर्ट करना शुरू कर देता है जो एक-दूसरे से मेल नहीं खाते.

इस वजह से, Bazel ट्रांज़िशनरी डिपेंडेंसी को अपने-आप डाउनलोड नहीं करता. माफ़ करें, इस समस्या का कोई आसान समाधान नहीं है. Bazel के लिए, एक ऐसी ग्लोबल फ़ाइल ज़रूरी है जिसमें रिपॉज़िटरी की हर एक बाहरी डिपेंडेंसी और पूरी रिपॉज़िटरी में उस डिपेंडेंसी के लिए इस्तेमाल किए गए वर्शन की जानकारी हो. सौभाग्य से, Bazel ऐसे टूल उपलब्ध कराता है जो Maven आर्टफ़ैक्ट के सेट की ट्रांज़िशन डिपेंडेंसी वाली फ़ाइल को अपने-आप जनरेट कर सकते हैं. किसी प्रोजेक्ट के लिए शुरुआती WORKSPACE फ़ाइल जनरेट करने के लिए, इस टूल को एक बार चलाया जा सकता है. इसके बाद, हर डिपेंडेंसी के वर्शन में बदलाव करने के लिए, उस फ़ाइल को मैन्युअल तरीके से अपडेट किया जा सकता है.

यहां भी, आपको सुविधा और स्केल करने की सुविधा में से किसी एक को चुनना होगा. छोटे प्रोजेक्ट में, ट्रांज़िशन डिपेंडेंसी को मैनेज करने की ज़रूरत नहीं होती. साथ ही, अपने-आप ट्रांज़िशन डिपेंडेंसी का इस्तेमाल किया जा सकता है. यह रणनीति, संगठन के तौर पर कम दिलचस्प होती जाती है और कोड बेस बढ़ता जाता है. साथ ही, कॉन्फ़्लिक्ट और अनचाहे नतीजे भी बढ़ता रहता है अक्सर. बड़े पैमाने पर, डिपेंडेंसी को मैन्युअल तौर पर मैनेज करने में आने वाला खर्च अपने-आप डिपेंडेंसी की वजह से होने वाली समस्याओं को हल करने में लगने वाले खर्च से कम है मैनेज करना.

बाहरी डिपेंडेंसी का इस्तेमाल करके, बिल्ड के नतीजों को कैश मेमोरी में सेव करना

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

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

आर्टफ़ैक्ट बनाने में ज़्यादा समय लगने से, समस्या को हल करने का एक बेहतर तरीका यह है कि जैसा कि ऊपर बताया गया है, ऐसे बिल्ड सिस्टम का इस्तेमाल करना होगा जो रिमोट कैशिंग की सुविधा देता हो. ऐसा बिल्ड सिस्टम, हर बिल्ड के आर्टफ़ैक्ट को ऐसी जगह सेव करता है जिसे सभी इंजीनियर शेयर करते हैं. इसलिए, अगर कोई डेवलपर किसी ऐसे आर्टफ़ैक्ट पर निर्भर करता है जिसे हाल ही में किसी और ने बनाया है, तो बिल्ड सिस्टम उसे बनाने के बजाय, अपने-आप डाउनलोड कर लेता है. इससे, सीधे आर्टफ़ैक्ट पर निर्भर रहने की परफ़ॉर्मेंस के सभी फ़ायदे मिलते हैं. साथ ही, यह भी पक्का किया जाता है कि बिल्ड एक जैसे हों, जैसे कि वे हमेशा एक ही सोर्स से बनाए गए हों. यह है रणनीति का इस्तेमाल Google अंदरूनी तौर पर करता है. साथ ही, Basel को रिमोट का इस्तेमाल करने के लिए कॉन्फ़िगर किया जा सकता है कैश मेमोरी.

बाहरी डिपेंडेंसी की सुरक्षा और विश्वसनीयता

तीसरे पक्ष के सोर्स से मिलने वाले आर्टफ़ैक्ट पर भरोसा करना, अपने-आप में जोखिम भरा होता है. अगर तीसरे पक्ष का सोर्स (जैसे, आर्टफ़ैक्ट रिपॉज़िटरी) काम नहीं करता है, तो उपलब्धता का खतरा होता है. ऐसा इसलिए, क्योंकि अगर बाहरी डिपेंडेंसी डाउनलोड नहीं हो पाती है, तो आपका पूरा बिल्ड रुक सकता है. सुरक्षा जोखिम भी होता है: अगर तीसरे पक्ष के सिस्टम ने किसी हमलावर ने छेड़छाड़ की है, तो हमलावर अपने खुद के किसी डिज़ाइन वाले आर्टफ़ैक्ट की मदद से, आर्बिट्रेरी कोड को इंजेक्ट कर सकता है आपके बिल्ड में इस्तेमाल हो सकता है. इन दोनों समस्याओं को कम करने के लिए, उन सभी आर्टफ़ैक्ट को अपने कंट्रोल वाले सर्वर पर मिरर करें जिन पर आपको निर्भर रहना है. साथ ही, अपने बिल्ड सिस्टम को Maven Central जैसे तीसरे पक्ष के आर्टफ़ैक्ट डेटा स्टोर को ऐक्सेस करने से रोकें. हालांकि, इनका रखरखाव करना आसान नहीं है. इसके लिए, समय और संसाधनों की ज़रूरत होती है. इसलिए, इनका इस्तेमाल करना या नहीं, यह प्रोजेक्ट के स्केल पर निर्भर करता है. सुरक्षा से जुड़ी समस्या को कम लागत में पूरी तरह से रोका जा सकता है. इसके लिए, सोर्स रिपॉज़िटरी में तीसरे पक्ष के हर आर्टफ़ैक्ट के हैश की ज़रूरत होती है. इससे, आर्टफ़ैक्ट में छेड़छाड़ होने पर बिल्ड पूरा नहीं हो पाता. एक और विकल्प, जो पूरी तरह से यह समस्या आपके प्रोजेक्ट की डिपेंडेंसी के लिए, वेंडर को करने में आती है. जब कोई प्रोजेक्ट अपनी डिपेंडेंसी को वेंडर करता है, तो वह उन्हें प्रोजेक्ट के सोर्स कोड के साथ सोर्स कंट्रोल में, सोर्स या बाइनरी के तौर पर जांचता है. इसका मतलब है कि प्रोजेक्ट की सभी बाहरी डिपेंडेंसी, अंदरूनी डिपेंडेंसी में बदल गई हैं. Google इस तरीके का इस्तेमाल अपने अंदर करता है. इसमें, Google के सोर्स ट्री के रूट में मौजूद third_party डायरेक्ट्री में, Google के पूरे प्लैटफ़ॉर्म पर रेफ़र की गई तीसरे पक्ष की हर लाइब्रेरी की जांच की जाती है. हालांकि, यह सिर्फ़ Google पर काम करता है, क्योंकि Google का सोर्स कंट्रोल सिस्टम, बहुत बड़े मोनोरेपो को मैनेज करने के लिए कस्टम तौर पर बनाया गया है. इसलिए, हो सकता है कि सभी संगठनों के लिए वेंडरिंग एक विकल्प न हो.