Gradle डिपेंडेंसी रिज़ॉल्यूशन

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

minor (नई सुविधाएं) या patch (बग ठीक करने वाले) हिस्सों में बदलाव होने पर, लाइब्रेरी अब भी काम कर सकती है. साथ ही, आपके ऐप्लिकेशन पर इसका कम असर पड़ेगा.

उदाहरण के लिए, मान लें कि आपका ऐप्लिकेशन लाइब्रेरी A और लाइब्रेरी B पर निर्भर करता है, जो बदले में लाइब्रेरी C के अलग-अलग वर्शन पर निर्भर करती हैं.

आपका ऐप्लिकेशन, लाइब्रेरी A और लाइब्रेरी B पर निर्भर करता है जो लाइब्रेरी C के अलग-अलग वर्शन पर निर्भर करते हैं. Gradle, लाइब्रेरी C का सबसे नया वर्शन चुनता है.
पहली इमेज. ट्रांज़िटिव वर्शन कॉन्फ़्लिक्ट. Gradle, डिफ़ॉल्ट रूप से सबसे नए वर्शन पर काम करता है.

इस मामले में, Gradle डिफ़ॉल्ट रूप से लाइब्रेरी C का नया वर्शन चुनता है. इससे, कॉम्पाइलेशन या रनटाइम से जुड़ी समस्याएं हो सकती हैं. इस उदाहरण में, लाइब्रेरी C को 2.1.1 पर अपडेट कर दिया गया है. हालांकि, ध्यान दें कि लाइब्रेरी A ने लाइब्रेरी C के 1.0.3 वर्शन का अनुरोध किया था. वर्शन नंबर का मुख्य हिस्सा बदल गया है. इससे पता चलता है कि वर्शन नंबर सही नहीं है. जैसे, हटाए गए फ़ंक्शन या टाइप. इस वजह से, लाइब्रेरी A से किए गए कॉल क्रैश हो सकते हैं.

आपके ऐप्लिकेशन की डायरेक्ट डिपेंडेंसी भी हो सकती हैं. ये ट्रांज़िटिव डिपेंडेंसी भी होती हैं.

आपका ऐप्लिकेशन, लाइब्रेरी A और लाइब्रेरी C पर निर्भर करता है. लाइब्रेरी A, लाइब्रेरी C के नए वर्शन पर निर्भर करती है. Gradle, लाइब्रेरी C का सबसे नया वर्शन चुनता है.
दूसरी इमेज. ट्रांज़िशन वर्शन से जुड़ा कोई दूसरा विरोध. इसमें Gradle, ट्रांज़िटिव वर्शन को प्रोसेस करता है और आपके ऐप्लिकेशन को नया वर्शन दिखता है.

इस तरह के मामले में, नई ट्रांज़िटिव डिपेंडेंसी अपने ऐप्लिकेशन में सीधे तौर पर अनुरोध किए गए वर्शन को बदल सकती हैं.

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

उदाहरण के लिए, ./gradlew app:dependencies चलाकर Gradle dependencies टास्क का इस्तेमाल किया जा सकता है. इससे, आपके ऐप्लिकेशन मॉड्यूल में इस्तेमाल की गई सभी डिपेंडेंसी का ट्री दिखता है. इसे एक ऐसे ऐप्लिकेशन पर चलाने पर जो लाइब्रेरी का इस्तेमाल करता है, जैसा कि इमेज 2 में दिखाया गया है, हमें पता चलता है कि

1: releaseRuntimeClasspath - Runtime classpath of /release.
2: +--- org.jetbrains.kotlin:kotlin-stdlib:2.0.0
3: |    +--- ... (omitted for brevity) ...
4: +--- com.sample:library.a:1.2.3
5: |    +--- com.sample:library.c:2.1.1
6: |    |    \--- org.jetbrains.kotlin:kotlin-stdlib:2.0.0 (*)
7: |    \--- org.jetbrains.kotlin:kotlin-stdlib:2.0.0 (*)
8: +--- com.sample:library.c:1.4.1 -> 2.1.1 (*)

रिपोर्ट के इस हिस्से में, releaseRuntimeClasspath कॉन्फ़िगरेशन के लिए हल की गई कुछ डिपेंडेंसी दिखती हैं.

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

Gradle की डिपेंडेंसी रिपोर्टिंग का इस्तेमाल करने के बारे में ज़्यादा जानकारी पाने के लिए, डिपेंडेंसी देखना और डिबग करना लेख पढ़ें.

अनुरोध किए गए वर्शन की जानकारी, सीधे वर्शन कैटलॉग या बिल ऑफ़ मटीरियल (बीओएम) में दी जा सकती है.

डायरेक्ट वर्शन स्पेसिफ़िकेशन का रिज़ॉल्यूशन

आपने जो डिपेंडेंसी के वर्शन तय किए हैं वे वर्शन रिज़ॉल्यूशन के लिए उम्मीदवार बन जाते हैं.

उदाहरण के लिए, अपने app/build.gradle.kts में डिपेंडेंसी के तौर पर androidx.compose.ui:ui लाइब्रेरी के 1.7.3 वर्शन का अनुरोध करने के लिए:

dependencies {
    implementation("androidx.compose.ui:ui:1.7.3")
}

वर्शन 1.7.3, उम्मीदवार वर्शन बन जाता है. Gradle, 1.7.3 और इसी लाइब्रेरी के अन्य वर्शन में से सबसे नए वर्शन पर काम करता है, जिसका अनुरोध अस्थायी डिपेंडेंसी के आधार पर किया जाता है.

वर्शन कैटलॉग का रिज़ॉल्यूशन

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

उदाहरण के लिए, अपनी gradle/libs.versions.toml फ़ाइल में androidx.compose.ui:ui के वर्शन 1.7.3 को डिपेंडेंसी के तौर पर बताने के लिए:

[versions]
ui = "1.7.3"

[libraries]
androidx-compose-ui = { group = "androidx.compose.ui", name = "ui", version.ref = "ui" }

यह लाइब्रेरी को दिखाने के लिए, libs.androidx.compose.ui नाम का एक वैरिएबल तय करता है. जब तक किसी डिपेंडेंसी के बारे में बताने के लिए उस वैरिएबल का इस्तेमाल नहीं किया जाता, तब तक इस वर्शन को उम्मीदवार के तौर पर नहीं माना जाता.

अपने app/build.gradle.kts में लाइब्रेरी और उसके वर्शन का अनुरोध करने के लिए:

dependencies {
    implementation(libs.androidx.compose.ui)
}

Gradle, सीधे तौर पर बताए गए स्पेसिफ़िकेशन की तरह ही, इस स्पेसिफ़िकेशन को भी हल करता है.

बिल ऑफ़ मटीरियल (बीओएम) से जुड़ी समस्या का हल

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

बीओएम वर्शन आपकी डायरेक्ट डिपेंडेंसी के साथ-साथ, बीओएम में दिखने वाली सभी ट्रांज़िटिव डिपेंडेंसी पर असर डालते हैं.

उदाहरण के लिए, अपने app/build.gradle.kts में किसी BOM को प्लैटफ़ॉर्म की डिपेंडेंसी के तौर पर तय करें:

dependencies {
    implementation(platform("androidx.compose:compose-bom:2024.10.00"))
    implementation("androidx.compose.ui:ui")
}

जिन लाइब्रेरी का इस्तेमाल डिपेंडेंसी के तौर पर करना है उनके लिए वर्शन की जानकारी ज़रूरी नहीं है. अनुरोध किया गया वर्शन, बीओएम से मिलता है.

ध्यान दें कि बीओएम और लाइब्रेरी के लिए वैरिएबल बनाने के लिए, वर्शन कैटलॉग का भी इस्तेमाल किया जा सकता है. बीओएम डिपेंडेंसी में दिखने वाली लाइब्रेरी के लिए, वर्शन कैटलॉग में दिए गए वर्शन नंबर को छोड़ दें.

उदाहरण के लिए, आपके वर्शन कैटलॉग में बीओएम और उसका वर्शन नंबर शामिल है, लेकिन उन लाइब्रेरी के लिए वर्शन तय नहीं करता जिनका रेफ़रंस आपने बीओएम से दिया है:

[versions]
composeBom = "2024.10.00"

[libraries]
androidx-compose-bom = { group = "androidx.compose", name = "compose-bom", version.ref = "composeBom" }
androidx-compose-ui = { group = "androidx.compose.ui", name = "ui" }

आपका app/build.gradle.kts, वर्शन कैटलॉग में तय किए गए वैरिएबल का इस्तेमाल करके, बीओएम और लाइब्रेरी का रेफ़रंस देता है:

dependencies {
    implementation(platform(libs.androidx.compose.bom))
    implementation(libs.androidx.compose.ui)
}

बीओएम में बताई गई लाइब्रेरी का वर्शन, Gradle के समाधान का उम्मीदवार बन जाता है. इसके अलावा, BOM में बताए गए लाइब्रेरी के सभी अन्य वर्शन, कैंडिडेट वर्शन बन जाते हैं. भले ही, आपने उन्हें सीधे तौर पर डिपेंडेंसी के तौर पर इस्तेमाल किया हो या नहीं.

उदाहरण के लिए, मान लीजिए कि BOM लाइब्रेरी के A, B, और C के लिए वर्शन तय करता है. आपका ऐप्लिकेशन, लाइब्रेरी A और लाइब्रेरी D, दोनों का इस्तेमाल डिपेंडेंसी के तौर पर करना चाहता है. लाइब्रेरी D, लाइब्रेरी B का इस्तेमाल डिपेंडेंसी के तौर पर करती है. लाइब्रेरी C का इस्तेमाल कुछ भी नहीं किया गया है.

बीओएम में लाइब्रेरी A, B, और C के वर्शन शामिल होते हैं. आपका ऐप्लिकेशन, लाइब्रेरी A और D का इस्तेमाल डिपेंडेंसी के तौर पर करता है. लाइब्रेरी D, लाइब्रेरी B का इस्तेमाल डिपेंडेंसी के तौर पर करती है. इस ऐप्लिकेशन में, लाइब्रेरी C का सीधे तौर पर या किसी अन्य तरीके से इस्तेमाल नहीं किया गया है.
तीसरी इमेज. BOM की स्थिति.

लाइब्रेरी A, B, और D, ऐप्लिकेशन की डिपेंडेंसी हैं. लाइब्रेरी C को अनदेखा किया जाता है. Gradle, BOM में बताए गए A और B के वर्शन का इस्तेमाल, उम्मीदवारों के तौर पर करता है. भले ही, आपने लाइब्रेरी B को सीधे तौर पर डिपेंडेंसी के तौर पर न बताया हो.

अगर लाइब्रेरी D ने लाइब्रेरी B के 2.0.1 से पहले के वर्शन का अनुरोध किया है, तो Gradle 2.0.1 आ जाता है. अगर लाइब्रेरी D ने लाइब्रेरी B के किसी नए वर्शन का अनुरोध किया है, तो Gradle उस वर्शन को हल करता है.