डिपेंडेंसी जोड़ने पर, आपको मूल डिपेंडेंसी के लिए ज़रूरी डिपेंडेंसी से जुड़ी समस्याएं आ सकती हैं. साथ ही, डिपेंडेंसी के अलग-अलग वर्शन के बीच विरोध भी हो सकता है. यहां अपने डिपेंडेंसी ग्राफ़ का विश्लेषण करने और उससे जुड़ी सामान्य समस्याओं को ठीक करने का तरीका बताया गया है.
कस्टम बिल्ड लॉजिक से जुड़ी, डिपेंडेंसी रिज़ॉल्यूशन की गड़बड़ियों को ठीक करने के बारे में जानने के लिए, डिपेंडेंसी रिज़ॉल्यूशन की कस्टम रणनीतियां देखें.
एआई प्रॉम्प्ट
डिपेंडेंसी रिज़ॉल्यूशन से जुड़ी गड़बड़ियों को डीबग करना
इस प्रॉम्प्ट में, डिपेंडेंसी से जुड़ी समस्याओं को डीबग करने में मदद मांगी जाती है.
Android Studio में, build.gradle फ़ाइल खोलकर इस प्रॉम्प्ट को चलाएं.
I'm getting the following error in my build: Conflict with dependency. Resolved versions for runtime classpath and compile classpath differ. What changes do I need to make to my dependencies to resolve this error.
मॉड्यूल की डिपेंडेंसी देखना
कुछ डायरेक्ट डिपेंडेंसी की अपनी डिपेंडेंसी हो सकती हैं. इन्हें ट्रांज़िशन डिपेंडेंसी कहा जाता है. आपको हर ट्रांज़िटिव डिपेंडेंसी को मैन्युअल तौर पर एलान करने की ज़रूरत नहीं है. Gradle, आपके लिए उन्हें अपने-आप इकट्ठा और जोड़ता है. Gradle के लिए Android प्लग इन, एक टास्क उपलब्ध कराता है. इसमें, किसी मॉड्यूल के लिए Gradle की हल की गई डिपेंडेंसी की सूची दिखती है.
हर मॉड्यूल के लिए, रिपोर्ट में डिपेंडेंसी को भी ग्रुप किया जाता है. यह ग्रुपिंग, बिल्ड वैरिएंट, टेस्टिंग सोर्स सेट, और क्लासपाथ के आधार पर की जाती है. यहां किसी ऐप्लिकेशन मॉड्यूल के डीबग बिल्ड वैरिएंट के रनटाइम क्लासपाथ और इंस्ट्रूमेंट किए गए टेस्ट सोर्स सेट के क्लासिक क्लासपाथ की सैंपल रिपोर्ट दी गई है.
debugRuntimeClasspath - Dependencies for runtime/packaging
+--- :mylibrary (variant: debug)
+--- com.google.android.material:material:1.0.0@aar
+--- androidx.appcompat:appcompat:1.0.2@aar
+--- androidx.constraintlayout:constraintlayout:1.1.3@aar
+--- androidx.fragment:fragment:1.0.0@aar
+--- androidx.vectordrawable:vectordrawable-animated:1.0.0@aar
+--- androidx.recyclerview:recyclerview:1.0.0@aar
+--- androidx.legacy:legacy-support-core-ui:1.0.0@aar
...
debugAndroidTest
debugAndroidTestCompileClasspath - Dependencies for compilation
+--- androidx.test.ext:junit:1.1.0@aar
+--- androidx.test.espresso:espresso-core:3.1.1@aar
+--- androidx.test:runner:1.1.1@aar
+--- junit:junit:4.12@jar
...
टास्क चलाने के लिए, यह तरीका अपनाएं:
- व्यू > टूल विंडो > Gradle चुनें. इसके अलावा, टूल विंडो बार में Gradle
पर भी क्लिक किया जा सकता है.
- AppName > टास्क > android को बड़ा करें और androidDependencies पर दो बार क्लिक करें. Gradle के टास्क को पूरा करने के बाद, आउटपुट दिखाने के लिए रन विंडो खुलनी चाहिए.
Gradle में डिपेंडेंसी मैनेज करने के बारे में ज़्यादा जानने के लिए, Gradle के उपयोगकर्ता के लिए बनी गाइड में डिपेंडेंसी मैनेज करने के बुनियादी दिशा-निर्देश देखें.
ट्रांज़िटिव डिपेंडेंसी को बाहर रखना
किसी ऐप्लिकेशन के बड़े होने पर, उसमें कई डिपेंडेंसी हो सकती हैं. इनमें डायरेक्ट डिपेंडेंसी और ट्रांज़िटिव डिपेंडेंसी (ऐसी लाइब्रेरी जिन पर आपके ऐप्लिकेशन की इंपोर्ट की गई लाइब्रेरी निर्भर करती हैं) शामिल हैं.
जिन ट्रांज़िशन डिपेंडेंसी की अब ज़रूरत नहीं है उन्हें बाहर रखने के लिए, यहां दिए गए exclude
कीवर्ड का इस्तेमाल किया जा सकता है:
Kotlin
dependencies { implementation("some-library") { exclude(group = "com.example.imgtools", module = "native") } }
Groovy
dependencies { implementation('some-library') { exclude group: 'com.example.imgtools', module: 'native' } }
टेस्ट कॉन्फ़िगरेशन से ट्रांज़िशन डिपेंडेंसी को बाहर रखना
अगर आपको अपनी जांचों से कुछ ट्रांज़िशन डिपेंडेंसी को बाहर रखना है, तो हो सकता है कि ऊपर दिया गया कोड सैंपल उम्मीद के मुताबिक काम न करे. ऐसा इसलिए होता है, क्योंकि टेस्ट कॉन्फ़िगरेशन (उदाहरण के लिए, androidTestImplementation
) मॉड्यूल के implementation
कॉन्फ़िगरेशन को बड़ा करता है. इसका मतलब है कि जब Gradle कॉन्फ़िगरेशन को हल करता है, तो इसमें हमेशा implementation
डिपेंडेंसी होती हैं.
इसलिए, अपने टेस्ट से ट्रांज़िशन डिपेंडेंसी को बाहर रखने के लिए, आपको ऐसा प्रोग्राम के रनटाइम पर करना होगा, जैसा कि यहां दिखाया गया है:
Kotlin
android.testVariants.all { compileConfiguration.exclude(group = "com.jakewharton.threetenabp", module = "threetenabp") runtimeConfiguration.exclude(group = "com.jakewharton.threetenabp", module = "threetenabp") }
Groovy
android.testVariants.all { variant -> variant.getCompileConfiguration().exclude group: 'com.jakewharton.threetenabp', module: 'threetenabp' variant.getRuntimeConfiguration().exclude group: 'com.jakewharton.threetenabp', module: 'threetenabp' }
ध्यान दें: अब भी डिपेंडेंसी ब्लॉक में exclude
कीवर्ड का इस्तेमाल किया जा सकता है. जैसा कि ट्रांज़िशन डिपेंडेंसी को बाहर रखें सेक्शन के मूल कोड सैंपल में दिखाया गया है. इससे, टेस्ट कॉन्फ़िगरेशन के लिए खास तौर पर बनाई गई ट्रांज़िशन डिपेंडेंसी को हटाया जा सकता है. ये डिपेंडेंसी, दूसरे कॉन्फ़िगरेशन में शामिल नहीं होती हैं.
डिपेंडेंसी रिज़ॉल्यूशन से जुड़ी गड़बड़ियां ठीक करना
अपने ऐप्लिकेशन प्रोजेक्ट में कई डिपेंडेंसी जोड़ने पर, हो सकता है कि डायरेक्ट और ट्रांज़िटिव डिपेंडेंसी एक-दूसरे से मेल न खाएं. Android Gradle प्लग इन, इन विरोधों को ठीक करने की कोशिश करता है. हालांकि, कुछ विरोधों की वजह से कंपाइल करने के समय या रनटाइम में गड़बड़ियां हो सकती हैं.
अपने ऐप्लिकेशन के डिपेंडेंसी ट्री की जांच करें और उन डिपेंडेंसी को ढूंढें जो एक से ज़्यादा बार या अलग-अलग वर्शन में दिखती हैं. इससे आपको यह पता लगाने में मदद मिलेगी कि कौनसी डिपेंडेंसी गड़बड़ियों का कारण बन रही हैं.
अगर आपको डुप्लीकेट डिपेंडेंसी की आसानी से पहचान नहीं हो पा रही है, तो डुप्लीकेट क्लास वाली डिपेंडेंसी खोजने के लिए, Android Studio के यूज़र इंटरफ़ेस (यूआई) का इस्तेमाल करें. इसके लिए, यह तरीका अपनाएं:
- मेन्यू बार से, नेविगेट करें > क्लास को चुनें.
- पॉप-अप खोज डायलॉग में, पक्का करें कि प्रोजेक्ट से बाहर के आइटम शामिल करें के बगल में मौजूद बॉक्स पर सही का निशान लगा हो.
- बिल्ड गड़बड़ी में दिखने वाली क्लास का नाम टाइप करें.
- क्लास की डिपेंडेंसी के नतीजों की जांच करें.
नीचे दिए गए सेक्शन में, डिपेंडेंसी रिज़ॉल्यूशन से जुड़ी अलग-अलग तरह की गड़बड़ियों के बारे में बताया गया है. साथ ही, उन्हें ठीक करने का तरीका भी बताया गया है.
डुप्लीकेट क्लास से जुड़ी गड़बड़ियां ठीक करना
अगर कोई क्लास, रनटाइम क्लासपाथ में एक से ज़्यादा बार दिखती है, तो आपको इस तरह का गड़बड़ी का मैसेज दिखता है:
Program type already present com.example.MyClass
आम तौर पर, यह गड़बड़ी इनमें से किसी एक वजह से होती है:
- बाइनरी डिपेंडेंसी में ऐसी लाइब्रेरी शामिल होती है जिसे आपके ऐप्लिकेशन में डायरेक्ट डिपेंडेंसी के तौर पर भी शामिल किया जाता है. उदाहरण के लिए, आपका ऐप्लिकेशन लाइब्रेरी A और लाइब्रेरी B पर सीधे तौर पर निर्भर करता है. हालांकि, लाइब्रेरी A में पहले से ही लाइब्रेरी B शामिल है.
- इस समस्या को हल करने के लिए, लाइब्रेरी B को डायरेक्ट डिपेंडेंसी के तौर पर हटाएं.
- आपके ऐप्लिकेशन में, एक ही लाइब्रेरी पर लोकल बाइनरी डिपेंडेंसी और रिमोट बाइनरी डिपेंडेंसी है.
- इस समस्या को हल करने के लिए, बाइनरी डिपेंडेंसी में से किसी एक को हटाएं.
क्लासपाथ के बीच होने वाले टकराव को ठीक करना
जब Gradle, कंपाइल क्लासपाथ को हल करता है, तो वह सबसे पहले रनटाइम क्लासपाथ को हल करता है. साथ ही, इस नतीजे का इस्तेमाल करके यह तय करता है कि कंपाइल क्लासपाथ में डिपेंडेंसी के कौनसे वर्शन जोड़े जाएं. दूसरे शब्दों में, रनटाइम क्लासपाथ, डाउनस्ट्रीम क्लासपाथ पर एक जैसी डिपेंडेंसी के लिए ज़रूरी वर्शन नंबर तय करता है.
आपके ऐप्लिकेशन के रनटाइम क्लासपाथ से यह भी तय होता है कि Gradle को ऐप्लिकेशन के टेस्ट APK के लिए, रनटाइम क्लासपाथ में मौजूद डिपेंडेंसी से मैच करने के लिए, वर्शन नंबर की ज़रूरत होगी. क्लासपाथ की हैरारकी के बारे में पहली इमेज में बताया गया है.
पहली इमेज. एक से ज़्यादा क्लासपाथ में दिखने वाली डिपेंडेंसी के वर्शन नंबर, इस क्रम के हिसाब से मेल खाने चाहिए.
जब एक ही डिपेंडेंसी के अलग-अलग वर्शन, कई क्लासपाथ में दिखते हैं, तो कॉन्फ़िगरेशन में विरोध हो सकता है. उदाहरण के लिए, जब आपके ऐप्लिकेशन में implementation
डिपेंडेंसी कॉन्फ़िगरेशन का इस्तेमाल करके डिपेंडेंसी का एक वर्शन शामिल हो और लाइब्रेरी मॉड्यूल में runtimeOnly
कॉन्फ़िगरेशन का इस्तेमाल करके डिपेंडेंसी का एक अलग वर्शन शामिल हो.
रनटाइम और कंपाइल टाइम क्लासपाथ पर डिपेंडेंसी को हल करते समय, Android Gradle प्लग इन 3.3.0 और उसके बाद के वर्शन, डाउनस्ट्रीम वर्शन के कुछ विरोधों को अपने-आप ठीक करने की कोशिश करते हैं. उदाहरण के लिए, अगर रनटाइम क्लासपाथ में लाइब्रेरी A का वर्शन 2.0 शामिल है और कंपाइल क्लासपाथ में लाइब्रेरी A का वर्शन 1.0 शामिल है, तो गड़बड़ियों से बचने के लिए प्लग इन, कंपाइल क्लासपाथ पर लाइब्रेरी A के वर्शन 2.0 को डिपेंडेंसी के तौर पर अपने-आप अपडेट कर देता है.
हालांकि, अगर रनटाइम क्लासपाथ में लाइब्रेरी A का वर्शन 1.0 शामिल है और कंपाइल क्लासपाथ में लाइब्रेरी A का वर्शन 2.0 शामिल है, तो प्लग इन, कंपाइल क्लासपाथ पर लाइब्रेरी A के वर्शन 1.0 पर डिपेंडेंसी को डाउनग्रेड नहीं करता. इसके बावजूद, आपको इस तरह की गड़बड़ी दिखती है:
Conflict with dependency 'com.example.library:some-lib:2.0' in project 'my-library'. Resolved versions for runtime classpath (1.0) and compile classpath (2.0) differ.
इस समस्या को हल करने के लिए, इनमें से कोई एक तरीका अपनाएं:
- अपनी लाइब्रेरी मॉड्यूल में, डिपेंडेंसी के पसंदीदा वर्शन को
api
डिपेंडेंसी के तौर पर शामिल करें. इसका मतलब है कि सिर्फ़ आपका लाइब्रेरी मॉड्यूल, डिपेंडेंसी का एलान करता है. हालांकि, ऐप्लिकेशन मॉड्यूल के पास भी ट्रांज़िटिव तौर पर, उसके एपीआई का ऐक्सेस होगा. - इसके अलावा, दोनों मॉड्यूल में डिपेंडेंसी का एलान किया जा सकता है. हालांकि, आपको यह पक्का करना होगा कि हर मॉड्यूल, डिपेंडेंसी के एक ही वर्शन का इस्तेमाल करता हो. पूरे प्रोजेक्ट की प्रॉपर्टी कॉन्फ़िगर करें, ताकि यह पक्का किया जा सके कि हर डिपेंडेंसी के वर्शन आपके पूरे प्रोजेक्ट में एक जैसे रहें.