2013-04-19 9 views
27

मैं निर्भरता अभिसरण मुद्दों की जांच के लिए मेवेन-एंफोर्स-प्लगइन का उपयोग करता हूं। एक सामान्य आउटपुट होगा:मैवेन निर्भरता अभिसरण समस्याओं को हल करना

[WARNING] Rule 1: org.apache.maven.plugins.enforcer.DependencyConvergence failed 
    with message: 
Failed while enforcing releasability the error(s) are [ 
Dependency convergence error for junit:junit:3.8.1 paths to dependency are: 
+-foo:bar:1.0-SNAPSHOT 
    +-ca.juliusdavies:not-yet-commons-ssl:0.3.9 
    +-commons-httpclient:commons-httpclient:3.0 
     +-junit:junit:3.8.1 
and 
+-foo:bar:1.0-SNAPSHOT 
    +-junit:junit:4.11 
] 

इस संदेश को देखते हुए, मैं सामान्य रूप से संक्रमणीय निर्भरता को छोड़कर इसे "हल" करता हूं, उदा।

<dependency> 
    <groupId>ca.juliusdavies</groupId> 
    <artifactId>not-yet-commons-ssl</artifactId> 
    <version>0.3.9</version> 
    <exclusions> 
    <!-- This artifact links to another artifact which stupidly includes 
     junit in compile scope --> 
    <exclusion> 
     <groupId>junit</groupId> 
     <artifactId>junit</artifactId> 
    </exclusion> 
    </exclusions> 
</dependency> 

मैं समझना चाहता हूं कि यह वास्तव में एक फिक्स है और इस फैशन में पुस्तकालयों को छोड़कर जोखिम शामिल है। जैसा कि मैंने इसे देखा:

  • "फिक्स" सामान्य रूप से सुरक्षित है, बशर्ते मैं नए संस्करण का उपयोग करना चुन रहा हूं। यह लाइब्रेरी लेखकों को पीछे की संगतता बनाए रखने पर निर्भर करता है।

  • आम तौर पर मेवेन बिल्ड (निकटतम परिभाषा जीतने के बाद) पर कोई प्रभाव नहीं पड़ता है, हालांकि निर्भरता को छोड़कर मैं मैवेन को बता रहा हूं कि मुझे इस समस्या के बारे में पता है और इस प्रकार मैवेन-एनफोर्स-प्लगइन को प्रसन्न करता है।

क्या मेरे विचार सही हैं और क्या इस मुद्दे को संभालने का कोई वैकल्पिक तरीका है? मुझे उन उत्तरों में दिलचस्पी है जो सामान्य मामले पर ध्यान केंद्रित करते हैं - मुझे लगता है कि ऊपर junit उदाहरण थोड़ा अजीब है।

उत्तर

39

हम सभी सहमत हैं कि जुनीट को कभी भी test से दूसरे दायरे पर सेट नहीं किया जाना चाहिए। आम तौर पर मैं यह नहीं सोचता कि अवांछित निर्भरता को छोड़कर एक और समाधान है, इसलिए हम सभी सहमत हैं कि आप इसे करने का अधिकार रखते हैं।

एक सरल मामला:

एंड्रियास ईद्भूजर कहते हैं, वहाँ संस्करणों के साथ एक जोखिम (मैं वास्तव में यह सामना करना पड़ा) हो सकता है। मान लें कि परियोजना की निर्भरता निम्न हैं:

+-foo:bar:1.0-SNAPSHOT 
    +-group1:projectA:2.0 
    +-group2:projectB:3.8.1 
    +-group2:projectB:4.11 

ध्यान दें कि यह केवल आपके मामले का एक सरलीकरण है।यह निर्भरता वृक्ष को देखकर, आप निर्भरता projectB PROJECTA द्वारा दिए गए बहिष्कृत कर देगा:

<dependency> 
    <groupId>group1</groupId> 
    <artifactId>projectA</artifactId> 
    <version>2.0</version> 
    <exclusions> 
    <exclusion> 
     <groupId>group2</groupId> 
     <artifactId>projectB</artifactId> 
    </exclusion> 
    </exclusions> 
</dependency> 

Maven के साथ इस परियोजना पैकेजिंग के बाद, शेष निर्भरता समूह 2-someProjectB-4.11.jar, संस्करण 4.11 और नहीं 3.8.1 होगा। सब कुछ ठीक होगा और परियोजना किसी भी समस्या का सामना किए बिना चलेगी।

फिर, कुछ समय के बाद, कहते हैं कि तुम परियोजना एक के अगले संस्करण में नवीनीकृत करने का फैसला करते हैं, संस्करण 3.0 नई महान सुविधाओं को जोड़ता है जो:

<dependency> 
    <groupId>group1</groupId> 
    <artifactId>projectA</artifactId> 
    <version>3.0</version> 
    <exclusions> 
    <exclusion> 
     <groupId>group2</groupId> 
     <artifactId>projectB</artifactId> 
    </exclusion> 
    </exclusions> 
</dependency> 

समस्या यह है कि आप अभी तक जानकारी नहीं है कि PROJECTA संस्करण 3.0 भी संस्करण 5.0 के लिए अपनी निर्भरता projectB को अपग्रेड किया है:

+-foo:bar:1.0-SNAPSHOT 
    +-group1:projectA:3.0 
    +-group2:projectB:5.0 
    +-group2:projectB:4.11 

उस मामले में, बहिष्कार आप थोड़ी देर पहले बना सकता था projectB संस्करण 5.0 शामिल नहीं है।

हालांकि, प्रोजेक्ट ए संस्करण 3.0 को प्रोजेक्ट बी संस्करण 5.0 से सुधार की आवश्यकता है। बहिष्कार के कारण, मैवेन के साथ प्रोजेक्ट को पैकेज करने के बाद, शेष निर्भरता समूह 2-कुछ प्रोजेक्ट बी-4.11.जर, संस्करण 4.11 और 5.0 नहीं होगी। फिलहाल आप प्रोजेक्ट ए की नई सुविधाओं का उपयोग करते हैं, प्रोग्राम सही ढंग से नहीं चलेंगे।

समाधान क्या था?

मुझे जावा-ईई प्रोजेक्ट में इस समस्या का सामना करना पड़ा।

एक टीम ने डेटाबेस सेवाओं को विकसित किया। उन्होंने इसे प्रोजेक्ट ए के रूप में पैक किया। प्रत्येक बार जब उन्होंने सेवाओं को अपडेट किया, तो उन्होंने अपनी सभी मौजूदा निर्भरताओं और वर्तमान संस्करणों को सूचीबद्ध करने वाली फ़ाइल को भी अपडेट किया।

प्रोजेक्टए जावा-ईई प्रोजेक्ट पर निर्भर था जिस पर मैं काम कर रहा था। प्रत्येक बार सेवा-टीम ने प्रोजेक्टए अपडेट किया, मैंने संस्करणों के अपडेट की भी जांच की।

वास्तव में, निर्भरता को छोड़कर कोई नुकसान नहीं होता है।

  • अगर यह बहिष्कार अभी भी समझ में आता है: लेकिन हर बार आप किसी निर्भरता जहां एक अपवर्जन स्थापित किया गया है अद्यतन करते हैं, आपको यह देखना होगा की है।
  • यदि आपको अपनी परियोजना में बहिष्कृत निर्भरता के संस्करण को अपग्रेड करना है।

मुझे लगता है कि मेवेन बहिष्कार रसोई के चाकू की तरह हैं। यह तेज है, सब्जियों को बिना किसी प्रयास के कटौती करता है, लेकिन इसे संभालने के दौरान देखभाल की आवश्यकता होती है ...

+1

एक बहुत अच्छी प्रतिक्रिया, धन्यवाद। मैंने बहिष्कार को बनाए रखने के खतरों के बारे में सोचा नहीं था। –

+0

मैंने आपके उत्तर में विस्तार के स्तर के कारण आपको बक्षीस से सम्मानित किया।यह एक अच्छा (कुछ हद तक) वास्तविक दुनिया का उदाहरण देखना अच्छा था कि यह गलत कैसे हो सकता है। –

+0

@DuncanJones धन्यवाद। मेरा जवाब एक समाधान की तुलना में एक चेतावनी है। फिर भी, मुझे आशा है कि इससे मदद मिलेगी। –

3

यदि एक आर्टिफैक्ट के रूप में जुनीट संकलन क्षेत्र में निर्भरता के रूप में आ रहा है, तो यह आपके पुस्तकालयों में से एक की एक बग है, यहां: ca.juliusdavies।

जुनीट को हमेशा टेस्ट स्कोप में शामिल किया जाना चाहिए। इस प्रकार, यह सफल निर्माण पर उत्पादित .jar, .war या .ear फ़ाइल में पैक किया गया है।

आम तौर पर, पहले से ही शामिल निर्भरताओं को छोड़कर कोई नुकसान नहीं होता है, जैसे लाइब्रेरी 1 और लाइब्रेरी 2 एक आम निर्भरता साझा करते हैं।

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

यदि नहीं, तो अपने प्रोजेक्ट की प्रथम-स्तर निर्भरताओं के लिए wheter जांचें।

+0

अपने पहले बिंदु के बारे में, हाँ आप सही हैं (इसलिए मेरे एक्सएमएल में टिप्पणी करने की आवश्यकता की मूर्खता को देखते हुए)। ऐसा लगता है जैसे हम आपके दूसरे बिंदु (पिछड़ा संगतता के संबंध में) से सहमत हैं। –

+0

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

संबंधित मुद्दे