मेरे कार्यालय में, Xerces शब्द का मात्र उल्लेख डेवलपर्स से जानलेवा गुस्से को उकसाने के लिए पर्याप्त है। एसओ पर अन्य Xerces प्रश्नों पर एक सरसरी नज़र से संकेत मिलता है कि लगभग सभी मावेन उपयोगकर्ता कुछ बिंदु पर इस समस्या से "छुआ" हैं। दुर्भाग्य से, समस्या को समझने के लिए Xerces के इतिहास के बारे में थोड़ी जानकारी की आवश्यकता है ...
इतिहास
Xerces जावा पारिस्थितिकी तंत्र में सबसे व्यापक रूप से इस्तेमाल किया जाने वाला XML पार्सर है। जावा में लिखा गया लगभग हर पुस्तकालय या ढांचा कुछ क्षमता में Xerces का उपयोग करता है (संक्रमणीय रूप से, यदि सीधे नहीं)।
आधिकारिक बायनेरीज़ में शामिल ज़ेरेस जार आज तक नहीं हैं। उदाहरण के लिए, Xerces 2.11.0 कार्यान्वयन जार का नाम दिया गया है
xercesImpl.jar
और नहींxercesImpl-2.11.0.jar
।Xerces टीम मावेन का उपयोग नहीं करती है , जिसका अर्थ है कि वे मावेन सेंट्रल को आधिकारिक रिलीज़ अपलोड नहीं करते हैं ।
Xerces को एक जार (
xerces.jar
) के रूप में जारी किया जाता था, लेकिन दो जार में विभाजित किया गया था, जिनमें से एक API (xml-apis.jar
) और एक उन API के कार्यान्वयन से युक्त था (xercesImpl.jar
)। कई पुराने मावेन पोम अब भी एक निर्भरता की घोषणा करते हैंxerces.jar
। अतीत में कुछ बिंदु पर, Xerces को भी जारी किया गया थाxmlParserAPIs.jar
, जो कुछ पुराने POMs पर भी निर्भर करता है।Xml-apis और xercesImpl jars को असाइन किए गए संस्करण, जो अपने जार को Maven रिपॉजिटरी में तैनात करते हैं, वे अक्सर भिन्न होते हैं। उदाहरण के लिए, xml-apis को संस्करण 1.3.03 दिया जा सकता है और xercesImpl को संस्करण 2.8.0 दिया जा सकता है, भले ही दोनों Xerces 2.8.0 से हो। ऐसा इसलिए है क्योंकि लोग अक्सर विनिर्देशों के संस्करण के साथ xml-apis जार को टैग करते हैं जो इसे लागू करता है। यहाँ इस का एक बहुत अच्छा, लेकिन अधूरा टूटना है ।
मामलों को जटिल करने के लिए, Xerces XML पार्सर है जिसे XML प्रसंस्करण के लिए जावा एपीआई (JAXP) के संदर्भ कार्यान्वयन में उपयोग किया जाता है, जो JRE में शामिल है। कार्यान्वयन कक्षाएं
com.sun.*
नाम-स्थान के तहत निरस्त कर दी जाती हैं , जो उन्हें सीधे एक्सेस करने के लिए खतरनाक बनाता है, क्योंकि वे कुछ राशियों में उपलब्ध नहीं हो सकते हैं। हालाँकि, सभी Xerces की कार्यक्षमताjava.*
औरjavax.*
API के माध्यम से उजागर नहीं होती है ; उदाहरण के लिए, कोई API नहीं है जो Xerces क्रमांकन को उजागर करता है।भ्रामक गंदगी को जोड़ते हुए, लगभग सभी सर्वलेट कंटेनर (JBoss, Jetty, Glassfish, Tomcat, आदि), उनके एक या एक से अधिक
/lib
फ़ोल्डरों में Xerces के साथ जहाज ।
समस्या
संघर्ष समाधान
उपरोक्त कारणों में से कुछ - या शायद सभी के लिए, कई संगठन अपने POMs में Xerces के कस्टम बिल्ड प्रकाशित और उपभोग करते हैं। यह वास्तव में एक समस्या नहीं है यदि आपके पास एक छोटा अनुप्रयोग है और केवल मावेन सेंट्रल का उपयोग कर रहे हैं, लेकिन यह जल्दी ही उद्यम सॉफ्टवेयर के लिए एक मुद्दा बन जाता है जहां आर्टिफ़ैक्ट्री या नेक्सस कई रिपॉजिटरी (JBoss, हाइबरनेट, आदि) का समर्थन कर रहा है:
उदाहरण के लिए, संगठन A के xml-apis
रूप में प्रकाशित हो सकता है :
<groupId>org.apache.xerces</groupId>
<artifactId>xml-apis</artifactId>
<version>2.9.1</version>
इस बीच, संगठन बी के jar
रूप में ही प्रकाशित हो सकता है :
<groupId>xml-apis</groupId>
<artifactId>xml-apis</artifactId>
<version>1.3.04</version>
हालाँकि B's jar
A की तुलना में कम संस्करण है jar
, लेकिन मावेन को यह पता नहीं है कि वे एक ही कलाकृति हैं क्योंकि उनके पास अलग-अलग हैं
groupId
। इस प्रकार, यह संघर्ष समाधान नहीं कर सकता है और दोनों
jar
को सुलझे हुए निर्भरता के रूप में शामिल किया जाएगा:
क्लास लोडर नर्क
जैसा कि ऊपर उल्लेख किया गया है, JREP RI में XRE के साथ JRE जहाज। जबकि सभी Xerces Maven निर्भरता को <exclusion>
s या के रूप में चिह्नित करना अच्छा होगा<provided>
आपके द्वारा उपयोग किए जा रहे तृतीय-पक्ष कोड आपके द्वारा उपयोग किए जा रहे JDK के JAXP में दिए गए संस्करण के साथ काम कर सकते हैं या नहीं भी कर सकते हैं। इसके अलावा, आपके पास अपने सर्वलेट कंटेनर में भेजे गए ज़ेरेस जार हैं जिनके साथ संघर्ष करना है। यह आपको कई विकल्पों के साथ छोड़ देता है: क्या आप सर्वलेट संस्करण को हटा देते हैं और आशा करते हैं कि आपका कंटेनर JAXP संस्करण पर चलता है? क्या सर्वलेट संस्करण को छोड़ना बेहतर है, और आशा है कि आपके आवेदन के ढांचे सर्वलेट संस्करण पर चलते हैं? यदि ऊपर उल्लिखित एक या दो अनसुलझे संघर्ष आपके उत्पाद में फिसलने का प्रबंधन करते हैं (एक बड़े संगठन में आसान होना), तो आप जल्दी से खुद को क्लासलोडर नरक में पाते हैं, यह सोचकर कि ज़ेरॉक्स का कौन सा संस्करण रन लोड पर उठा रहा है या नहीं विंडोज और लिनक्स में एक ही जार चुनेंगे (शायद नहीं)।
समाधान?
हम के रूप में सभी Xerces Maven निर्भरता अंकन की कोशिश की है <provided>
या एक के रूप में <exclusion>
, लेकिन यह देखते हुए लागू करने के लिए (विशेष रूप से एक बड़ी टीम के साथ) के लिए मुश्किल है कि कलाकृतियों इतने सारे उपनाम (है xml-apis
, xerces
, xercesImpl
, xmlParserAPIs
, आदि)। इसके अतिरिक्त, JAXP संस्करण या किसी सर्वलेट कंटेनर द्वारा उपलब्ध कराए गए संस्करण पर हमारी तीसरी पार्टी के काम / फ्रेमवर्क नहीं चल सकते हैं।
हम मावेन के साथ इस समस्या का सबसे अच्छा समाधान कैसे कर सकते हैं? क्या हमें अपनी निर्भरता पर इस तरह के बारीक नियंत्रण का प्रयोग करना होगा, और फिर टियरड क्लासलोडिंग पर भरोसा करना होगा? क्या किसी तरह से विश्व स्तर पर सभी Xerces निर्भरता को बाहर करने के लिए, और JAXA संस्करण का उपयोग करने के लिए हमारे सभी चौखटे / लिबास को मजबूर करने का कोई तरीका है?
अद्यतन : यहोशू Spiewak ने XERESJ-1454 में Xerces build स्क्रिप्ट का एक पैच संस्करण अपलोड किया है जो Maven Central में अपलोड करने की अनुमति देता है। इस मुद्दे पर वोट दें / देखें / योगदान करें और इस समस्या को एक बार और सभी के लिए ठीक करें।