2009-11-17 15 views
14

हम अपने ऐप के आरईएसटी एपीआई से कनेक्ट करने के लिए अन्य आंतरिक ऐप्स के लिए क्लाइंट जार प्रदान कर रहे हैं। हमारा एपीआई कुछ मानक जकार्ता पुस्तकालयों पर निर्भर करता है। क्या यह हमारी जेएआर फाइलों को हमारे क्लाइंट जार फ़ाइल में शामिल करने का सबसे अच्छा अभ्यास है? या आप केवल निर्भरताओं को दस्तावेज करते हैं और यह सुनिश्चित करने के लिए ग्राहकों पर निर्भर करता है कि उनके पास उनके वर्गपैठ पर उन जार हैं?क्या आपको क्लाइंट जार में निर्भर पुस्तकालय प्रदान करना चाहिए?

उत्तर

12

आप नहीं एक uber जार के रूप में अपने स्वयं के जार में किसी भी तीसरे पक्ष जार बंडल चाहिए, लेकिन इसके बारे में सभी जार के कि अपने वितरण में आवश्यक हैं एक lib निर्देशिका या क्या में कहते हैं कि एक प्रति शामिल करने के लिए अच्छा होगा कभी।

इसका मुख्य कारण यह है कि आपके ग्राहक कुछ निर्भरता प्रबंधन प्रणाली (मेवेन/आईवी इत्यादि) का उपयोग कर रहे हैं और पैकेज और कक्षाएं प्रदान कर रहे हैं जो वास्तव में आपके प्रोजेक्ट से संबंधित नहीं हैं, इन योजनाओं को अमान्य कर देंगे।

एक विकल्प है और maven shade plugin जैसे कुछ अपने उपयोग को अपने पैकेज नामस्थान में स्थानांतरित करने के लिए उपयोग करना है। बेशक यह नीचे की तरफ है कि आप अपनी लाइब्रेरी के कोड आकार को बढ़ाएंगे लेकिन ऊपर की तरफ आप अपने निर्भरताओं के संस्करणों को लगभग किसी भी अन्य पुस्तकालयों को प्रभावित करने के साथ गारंटी दे सकते हैं जो आपके क्लाइंट का उपयोग कर रहे हैं।

संपादित करें:/बाहर बंडलिंग साथ

संभावित समाधान स्थानांतरित:: मार्कस लियोन टिप्पणी के जवाब में

  • प्रलेखन, सुनिश्चित करें कि आप अपने निर्भरता और पिछले संस्करणों के साथ किसी भी ज्ञात विरोध के दस्तावेज़ बनाने - कोई भी नहीं वास्तव में इसे पढ़ता है
  • एक निर्भरता प्रबंधित प्रणाली के माध्यम से आपको लाइब्रेरी वितरित करें ... एक मेवेन या आईवी रेपो की तरह, ये आपको सीमाओं के एक बहुत ही विशिष्ट सेट (ऊपरी समेत) में दस्तावेज़ करने की अनुमति देता है जो आपकी निर्भरताएं हैं - अभी भी हो सकता है बस अपने ग्राहकों को अधिरोहित पता चल जाएगा कि वे इसे
  • कर रहे हैं MANIFEST.MF में OSGi जानकारी जोड़ें - केवल उपयोगी अगर अपने ग्राहकों को वास्तव में OSGi
  • का उपयोग अपने निर्भरता Maven का उपयोग करके बनाया गया है या वहाँ प्रकट फ़ाइलों में संस्करण जानकारी है आपको लगता है कि इन और वहाँ चेकों संस्करणों के लिए classpath को स्कैन करता है की जाँच दिनचर्या के कुछ प्रकार लिख सकते हैं - थोड़ा चरम

अंत में यह है अत्यंत कठिन करने के लिए वास्तव में सुनिश्चित करें कि आप निर्भरता आप जावा के रूप में चाहते हैं एक देर से बाध्य है भाषा क्लासपाथ पर आपके सामने एक अलग संस्करण सहित किसी भी व्यक्ति द्वारा आपकी निर्भरताओं (यहां तक ​​कि बंडल) को ओवरराइड करना संभव है।

नोट: मैंने हाल ही में बहुत बिताया है कि यह पता लगाने की कोशिश कर रहा है कि हमारे ऐप्स में से कोई एक log4j का नया संस्करण क्यों नहीं ढूंढ पाया। कारण: कोई भी सहायक होने की कोशिश कर रहा था, इसे एक यादृच्छिक पूरी तरह से असंबंधित जार में बंडल कर दिया था।

+0

यदि आप बंडल नहीं करते हैं, और आपका क्लाइंट dependent.jar के एक अलग संस्करण का उपयोग करता है, तो आप कैसे सुनिश्चित करते हैं कि client.jar dependent.jar के सही संस्करण का संदर्भ देता है? –

+1

संपादित देखें ...संक्षिप्त जवाब यह है कि आप कैसे नहीं कर सकते हैं ... भले ही आप –

+0

बंडल करते हैं, भले ही आप अभिव्यक्तियों को क्लास-पथ सेट के साथ एक जार में बंडल कर रहे हों, भले ही संकलक स्पष्ट रूप से उल्लिखित जार फ़ाइलों को लोड न करे कक्षा पथ प्रकट प्रविष्टि? –

2

यदि आप ऐप को एक स्टैंडअलोन एप्लिकेशन के रूप में तैनात कर रहे हैं तो आपको उन जारों को शामिल करना चाहिए। यदि आप किसी के निर्माण के लिए स्रोत तैनात कर रहे हैं और आप एक मेवेन पोम फ़ाइल प्रदान करते हैं तो आपको जरूरी नहीं है।

5

आपको किसी भी जार को शामिल करना चाहिए जिसमें आप निर्भर हैं। यदि आप क्लाइंट को मानक जार प्रदान करने की अनुमति देते हैं, तो आप सही संस्करण की आपूर्ति करने के लिए उन पर भरोसा करते हैं। यदि आप उन संस्करणों को शामिल करते हैं जो आप जानते हैं कि आपका ऐप काम करता है तो यह आपके लिए बहुत अधिक दर्द रहित है।

+0

यदि आप अपने जार के संस्करण # 2 को शामिल करते हैं और क्लाइंट के पास क्लासपाथ पर पहले से संस्करण # 1 है, तो आप कैसे लागू करते हैं कि आपकी लाइब्रेरी संस्करण # 2 (और v # 1 नहीं) का उपयोग करती है? –

+2

आप अपने आवेदन जार की मेनिफेस्ट फ़ाइल में अपने आवेदन के लिए क्लासपाथ निर्दिष्ट कर सकते हैं। (http://java.sun.com/docs/books/tutorial/deployment/jar/downman.html) क्लासस्पैट परिभाषा (जैसा कि पर्यावरण चर द्वारा परिभाषित किया गया है) जार के प्रकट द्वारा परिभाषित "वर्ग-पथ" द्वारा ओवरराइड किया गया है । –

+0

मैंने पढ़ा है (http://one-jar.sourceforge.net/) कि "जावा क्लासलोडर को पता नहीं है कि जार के अंदर जार से कक्षाएं कैसे लोड करें। क्लास-पथ पर प्रविष्टियां फाइलों के संदर्भ हों जार फ़ाइल के बाहर, एक जार फ़ाइल में एप्लिकेशन देने के लक्ष्य को हराया। " –

4

एक भी जार में bundling के पेशेवरों स्पष्ट रूप से कर रहे हैं: ग्राहक

bundling के विपक्ष के लिए

  • सादगी हैं:

    • के संस्करणों को अद्यतन करने में असमर्थता आश्रित पुस्तकालय
    • आवश्यक पुस्तकालयों को छिपाने से वास्तव में ग्राहक बुद्धि में संभावित संघर्ष हो सकते हैं निर्माण प्रक्रिया में आप के लिए ज उन अतिरिक्त पुस्तकालयों
    • जटिलता (लेकिन तरीके चींटी/Maven में बहुत आसानी से ऐसा करने के लिए)
    • प्रकट होता है के साथ कुछ पुस्तकालयों सिर्फ unjared नहीं हो सकता है और rejared कर सकते हैं - आप वास्तव में प्रकट जानकारी मर्ज करने के लिए की जरूरत है। हालांकि इसके लिए चींटी और मेवेन का समर्थन है।

    एक और विकल्प अन्य जार में चूसने के लिए सेट क्लास-पथ मेनिफेस्ट विशेषता के साथ एक मुख्य जार (आपका कोड) का उपयोग करना है। व्यक्तिगत रूप से मुझे यह पसंद नहीं है क्योंकि इन अर्ध-छिपी निर्भरताओं को याद करना वास्तव में आसान है।

    अंत में, यदि आप केवल एक या दो जार बात कर रहे हैं, तो मैं उन्हें अलग कर दूंगा। यदि आप 10 या 15 बात कर रहे हैं, तो आप बंडलिंग पर विचार करना चाहेंगे।

0

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

यदि आपको पता है कि एक पैकेज को एक बड़े मंच के हिस्से के रूप में काम करने की आवश्यकता है (कहें, एक ढांचे के लिए एक प्लगइन के रूप में जो अपने स्वयं के जार लोड कर रहा हो), तो आपको वास्तव में अधिक शक्तिशाली बहु-संस्करण वाली कक्षा-लोडिंग की आवश्यकता है OSGi (उर्फ JSR-291): OSGI Technology

एक OSGi सक्षम ढांचे के साथ

, स्प्रिंग, ग्रहण, जोनास, या Glassfish की तरह, आप अपने विशिष्ट संस्करण निर्भरता फ़ाइल एक XML में निर्दिष्ट कर सकता है, और आप बंडल पर निर्भर करता है, तो libfoo-1.1.4, जबकि एक और प्लगइन libfoo-2.0a पर निर्भर करता है, ओएसजीआई निर्भरता प्रबंधक प्रत्येक लोड को सही संस्करण सुनिश्चित करेगा।

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

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