एक "छायांकित" जावा निर्भरता क्या है?


74

जेवीएम डेवलपर यहाँ। हाल ही में मैंने आईआरसी चैट रूम और यहां तक ​​कि अपने स्वयं के कार्यालय में तथाकथित " छायांकित " जावा पुस्तकालयों पर प्रतिबंध देखा है। उपयोग का संदर्भ कुछ इस प्रकार होगा:

" ऐसा है और इसलिए XYZ के लिए एक" छायांकित "क्लाइंट प्रदान करता है। "

बिल्कुल सही उदाहरण HBase के लिए यह जीरा मुद्दा है : " छायांकित निर्भरताओं के साथ ग्राहक की कलाकृतियों को प्रकाशित करें "

तो मैं पूछता हूं: एक छायांकित जार क्या है, "छायांकित" होने का क्या मतलब है?

जवाबों:


86

छायांकन निर्भरता एक निजी प्रति बनाने के लिए निर्भरता को शामिल करने और नाम बदलने की प्रक्रिया है (इस प्रकार कक्षाएं और पुनर्लेखन प्रभावित बायोटेक एंड रिसोर्सेज को) जो आप अपने स्वयं के कोड के साथ बंडल करते हैं

अवधारणा आमतौर पर uber-jars (उर्फ वसा जार ) के साथ जुड़ा हुआ है ।

मावेन शेड प्लगइन के कारण शब्द के बारे में कुछ भ्रम है , जिसके तहत एक ही नाम 2 चीजें करता है (उनके पृष्ठ को उद्धृत करते हुए):

यह प्लगइन एक uber-jar में विरूपण साक्ष्य को पैकेज करने की क्षमता प्रदान करता है, जिसमें इसकी निर्भरता और छाया भी शामिल है - यानी नाम बदलें - कुछ निर्भरता के पैकेज।

तो छायांकन हिस्सा वास्तव में वैकल्पिक है: प्लगइन आपके जार (वसा जार) में निर्भरता को शामिल करने की अनुमति देता है, और वैकल्पिक रूप से नाम (शेड) निर्भरता को बदल देता है

एक और स्रोत जोड़ना :

एक पुस्तकालय के लिए कहा पुस्तकालय की सामग्री फ़ाइलों को लेने के लिए, उन्हें अपने जार में डाल दिया है, और उनके पैकेज को बदल सकते हैं । यह पैकेजिंग से अलग है जो बस पुस्तकालयों की फाइलों को आपके अपने जार में एक अलग पैकेज में स्थानांतरित किए बिना शिपिंग कर रहा है।

तकनीकी रूप से, निर्भरता को छायांकित किया जाता है। लेकिन एक मोटे-जार-साथ-छायांकित-निर्भरता को "छायांकित जार" के रूप में संदर्भित करना आम है, और यदि वह जार किसी अन्य सिस्टम के लिए क्लाइंट है, तो इसे "शेड्ड क्लाइंट" के रूप में संदर्भित किया जा सकता है।

यहाँ HBase के लिए जीरा मुद्दे का शीर्षक है जिसे आपने अपने प्रश्न में जोड़ा है:

छायांकित निर्भरता के साथ एक ग्राहक विरूपण साक्ष्य प्रकाशित करें

तो इस पोस्ट में मैं 2 अवधारणाओं को बिना बताए प्रस्तुत करने की कोशिश कर रहा हूं।

अच्छा

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

उबेर-जार बनाने के कई तरीके हैं, लेकिन maven-shade-pluginइसकी कक्षा स्थानांतरण सुविधा के साथ एक कदम आगे जाता है :

यदि uber JAR को किसी अन्य परियोजना की निर्भरता के रूप में पुन: उपयोग किया जाता है, तो सीधे uber JAR में विरूपण साक्ष्य की निर्भरता से कक्षाओं सहित, वर्ग पथ पर डुप्लिकेट कक्षाओं के कारण वर्ग लोडिंग संघर्ष हो सकता है। इस मुद्दे को संबोधित करने के लिए, कोई भी उन वर्गों को स्थानांतरित कर सकता है जो छायांकित विरूपण साक्ष्य में शामिल हो जाते हैं ताकि उनके बाइटकोड की एक निजी प्रतिलिपि बनाई जा सके।

(ऐतिहासिक नोट: जार जार लिंक्स ने पेशकश की कि पुनर्वास सुविधा से पहले)

तो इसके साथ आप अपने पुस्तकालय निर्भरता को एक कार्यान्वयन विवरण बना सकते हैं , जब तक कि आप अपने एपीआई में उन पुस्तकालयों से कक्षाओं को उजागर नहीं करते हैं।

मान लीजिए कि मैं एक परियोजना, ACME Quantanizer ™, जो प्रदान करता है चलो DecayingSyncQuantanizerवर्ग, और अपाचे कॉमन्स-RNG पर निर्भर करता है (क्योंकि निश्चित रूप से ठीक से आप एक की जरूरत है quantanize लिए XorShift1024Starओह,)।

अगर मैं uber-jar का उत्पादन करने के लिए शेड maven प्लगइन का उपयोग करता हूं, और मैं अंदर देखता हूं, तो मैं इन क्लास फ़ाइलों को देखता हूं:

com/acme/DecayingSyncQuantanizer.class
org/apache/commons/rng/RandomProviderState.class
org/apache/commons/rng/RestorableUniformRandomProvider.class
...
org/apache/commons/rng/core/source64/XorShift1024Star.class
org/apache/commons/rng/core/util/NumberFactory.class

अब अगर मैं क्लास-रिलॉकेटिंग फ़ीचर का उपयोग करता हूँ:

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-shade-plugin</artifactId>
  <version>3.0.0</version>
  <executions>
    <execution>
      <phase>package</phase>
      <goals>
        <goal>shade</goal>
      </goals>
      <configuration>
        <relocations>
          <relocation>
            <pattern>org.apache.commons</pattern>
            <shadedPattern>com.acme.shaded.apachecommons</shadedPattern>
          </relocation>
        </relocations>
      </configuration>
    </execution>
  </executions>
</plugin>

उबेर-जार की सामग्री इस तरह दिखती है:

com/acme/DecayingSyncQuantanizer.class
com/acme/shaded/apachecommons/rng/RandomProviderState.class
com/acme/shaded/apachecommons/rng/RestorableUniformRandomProvider.class
...
com/acme/shaded/apachecommons/rng/core/source64/XorShift1024Star.class
com/acme/shaded/apachecommons/rng/core/util/NumberFactory.class

यह सिर्फ फाइलों का नाम नहीं बदल रहा है, यह बाइटकोड को फिर से लिखता है जो कि स्थानांतरित वर्गों को संदर्भित करता है (इसलिए, मेरी अपनी कक्षाएं और कॉमन्स-रींग कक्षाएं सभी रूपांतरित हैं)।

इसके अलावा, शेड प्लगइन एक नया POM ( dependency-reduced-pom.xml) भी उत्पन्न करेगा जिसमें छायांकित निर्भरताएं <dependencies>अनुभाग से हटा दी जाती हैं । यह दूसरे प्रोजेक्ट के लिए निर्भरता के रूप में छायांकित जार का उपयोग करने में मदद करता है। तो आप उस जार को बेस एक, या दोनों (छायांकित जार के लिए क्वालिफायर का उपयोग करके) प्रकाशित कर सकते हैं ।

ताकि बहुत उपयोगी हो सके ...

खराब

... लेकिन इसमें कई मुद्दे हैं। जार के भीतर सभी आश्रितों को एकल "नामस्थान" में एकत्रित करने से गड़बड़ हो सकती है, और संसाधनों के साथ छायांकन और गड़बड़ी की आवश्यकता होती है।

उदाहरण के लिए: क्लास या पैकेज नामों में शामिल संसाधन फ़ाइलों से कैसे निपटें? सेवा प्रदाता डिस्क्रिप्टर जैसी संसाधन फाइलें जो सभी के अधीन रहती हैं META-INF/services?

छाया प्लगइन संसाधन ट्रांसफार्मर प्रदान करता है जो इसके साथ मदद कर सकते हैं:

जब तक कोई ओवरलैप न हो, एक uber JAR में कई कलाकृतियों से कक्षाओं / संसाधनों को इकट्ठा करना। अन्यथा, कई JAR से संसाधनों को मर्ज करने के लिए किसी प्रकार के तर्क की आवश्यकता होती है। यह वह जगह है जहाँ संसाधन ट्रांसफार्मर अंदर किक करते हैं।

लेकिन यह अभी भी गड़बड़ है, और समस्याओं का पूर्वानुमान लगाना लगभग असंभव है (बहुत बार आप उन मुद्दों की खोज करते हैं जो उत्पादन में कठिन रास्ता है)। देखें क्यों-हम-बंद कर दिया निर्माण वसा-जार

सब सब में, एक स्टैंडअलोन ऐप / सेवा के रूप में एक मोटी जार को तैनात करना अभी भी बहुत आम है, आपको बस गोचरों के बारे में पता होना चाहिए, और उनमें से कुछ के लिए आपको छायांकन या अन्य चाल की आवश्यकता हो सकती है ।

बदसूरत

कई और अधिक कठिन मुद्दे हैं (डिबगिंग, परीक्षण क्षमता, OSGi और विदेशी क्लास लोडर के साथ संगतता ...)।

लेकिन इससे भी महत्वपूर्ण बात यह है कि जब आप एक पुस्तकालय का निर्माण करते हैं, तो आपके द्वारा नियंत्रित किए जाने वाले विभिन्न मुद्दे अब असीम रूप से जटिल होते जा रहे हैं, क्योंकि आपके जार का उपयोग कई अलग-अलग संदर्भों में किया जाएगा (वसा जार के विपरीत जिसे आप स्टैंडअलोन ऐप या सेवा के रूप में तैनात करते हैं) एक नियंत्रित वातावरण में)।

उदाहरण के लिए, इलास्टिकसर्च ने अपने द्वारा भेजे गए जार में कुछ निर्भरता को छाया करने के लिए इस्तेमाल किया, लेकिन उन्होंने ऐसा करने से रोकने का फैसला किया :

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

कृपया ध्यान दें कि वे भी छायांकित निर्भरता का उल्लेख करते हैं , छायांकित जार का नहीं


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

उत्कृष्ट स्पष्टीकरण, मुझे लगता है कि इसे आधिकारिक डॉक्स में शामिल किया जाना चाहिए
एडेलिन

7

मुझे सॉफ्टवेयर की मदद से इस सवाल का जवाब देना चाहिए कि छायांकित जार बनाने के लिए वास्तव में जिम्मेदार ... कम से कम मावेन का उपयोग करते समय।

अपाचे मावेन शेड प्लगइन होम पेज से लिया गया :

यह प्लगइन एक उबेर-जार में विरूपण साक्ष्य को पैकेज करने की क्षमता प्रदान करता है, जिसमें इसकी निर्भरता और छाया भी शामिल है - यानी नाम - कुछ निर्भरता के पैकेज।

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


1
यह जवाब अधूरा है: यह बताता है कि वसा / ऊबर जार क्या है, लेकिन छायांकन भाग को स्पष्ट नहीं करता है । और हाँ, छायांकन "जार नरक" (जो उस उत्तर के अंतिम भाग को गलत बनाता है) के साथ मदद करने वाला है। तो यह कुछ स्तर पर उपयोगी है, लेकिन भ्रम में जोड़ता है: - /
ह्यूजेस एम।

1
@ ह्यूजेसमोरो मेरी प्रतिक्रिया में 100% पूर्ण नहीं हो सकता है, लेकिन यह अभी भी वह बिंदु लाया है जिसे मैं बनाना चाहता था। लापता भाग को मेज पर लाने के लिए धन्यवाद। छायांकन जार नरक से बचना नहीं है, यही मेरा मतलब है और लिखा है, लेकिन यह आपको हाथ में कुछ उपकरण देगा कि चलो आप इसकी कुछ समस्याओं को हल करते हैं, लेकिन यह स्वचालित नहीं है। जो पिछले हिस्से को पढ़ता है और अगर मेरे मतलब के तरीके को पढ़ता है, तो कम से कम ठीक है। :)
जेसको आर।
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.