मावेन के साथ एक जार में निर्भरता भी शामिल है


353

क्या एक जार फ़ाइल में सभी निर्भरताओं को शामिल करने के लिए मावेन (2.0.9) को मजबूर करने का एक तरीका है?

मैं एक परियोजना एक जार फ़ाइल में बनाता है। मैं चाहता हूं कि निर्भरता से वर्गों को भी जार में कॉपी किया जाए।

अद्यतन: मुझे पता है कि मैं सिर्फ एक जार फ़ाइल में एक जार फ़ाइल शामिल नहीं कर सकता। मैं जार को अनपैक करने के लिए एक तरीका खोज रहा हूं जो कि निर्भरता के रूप में निर्दिष्ट है, और वर्ग फ़ाइलों को मेरे जार में पैकेज करें।




2
मरीन में जार फ़ाइल को जार फ़ाइल में कैसे शामिल करें?
कुश पटेल

जवाबों:


488

आप "जार-साथ-निर्भरताएं" विवरणक के साथ मावेन-असेंबली प्लगइन का उपयोग करके ऐसा कर सकते हैं। यहाँ हमारे pom.xml में से एक से प्रासंगिक हिस्सा है जो ऐसा करता है:

  <build>
    <plugins>
      <!-- any other plugins -->
      <plugin>
        <artifactId>maven-assembly-plugin</artifactId>
        <executions>
          <execution>
            <phase>package</phase>
            <goals>
              <goal>single</goal>
            </goals>
          </execution>
        </executions>
        <configuration>
          <descriptorRefs>
            <descriptorRef>jar-with-dependencies</descriptorRef>
          </descriptorRefs>
        </configuration>
      </plugin>
    </plugins>
  </build>

30
attachedलक्ष्य मान्य नहीं है। singleया directory-singleलक्ष्य के बजाय प्राथमिकता दी जानी चाहिए।
पास्कल थिवेंट

16
directory-singleअब के रूप में अच्छी तरह से पदावनत है।
जेम्स मैकमोहन

14
आधिकारिक वेबसाइट पर सिंगल का उपयोग करने की सिफारिश की गई है
mateuszb

42
यदि कोई नया एमवीएन लोग मेरी तरह फंस गए, तो प्लगइन्स को <प्लगइन्स> <बिल्ड> के अंदर जोड़ें जो कि <प्रोजेक्ट> के अंदर है।
DA

10
@ Christian.tucker इस तरह बनाई गई टारगेट डायरेक्टरी में 2nd जार है ।/target/example-0.0.1-SNAPSHOT.jar और ./target/example-0.0.1-SNAPSHOT-jar-ith-dependencies.jar
टेक्नोक्रेट

145

Maven 2 के साथ, ऐसा करने का सही तरीका Maven2 असेंबली प्लगिन का उपयोग करना है जिसमें इस उद्देश्य के लिए पूर्व-परिभाषित डिस्क्रिप्टर फ़ाइल है और जिसे आप कमांड लाइन पर उपयोग कर सकते हैं:

mvn assembly:assembly -DdescriptorId=jar-with-dependencies

यदि आप इस जार को निष्पादन योग्य बनाना चाहते हैं, तो प्लग इन को चलाने के लिए मुख्य वर्ग को जोड़ें:

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-assembly-plugin</artifactId>
  <configuration>
    <archive>
      <manifest>
        <mainClass>my.package.to.my.MainClass</mainClass>
      </manifest>
    </archive>
  </configuration>
</plugin>

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

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-assembly-plugin</artifactId>
  <executions>
    <execution>
      <id>create-my-bundle</id>
      <phase>package</phase>
      <goals>
        <goal>single</goal>
      </goals>
      <configuration>
        <descriptorRefs>
          <descriptorRef>jar-with-dependencies</descriptorRef>
        </descriptorRefs>
        ...
      </configuration>
    </execution>
  </executions>
</plugin>

एडाप्ट करें configurationअपनी आवश्यकताओं के अनुरूप करने के तत्व को (उदाहरण के लिए बोले गए रूप में सामान के साथ)।


मैं वास्तव में यह कोशिश कर रहा हूं, हालांकि प्लगइन नहीं चलाया गया है और जार फ़ाइल तब भी नहीं बनाई गई है जब बिल्ड आसानी से निष्पादित होता है। वहाँ एक आम नुकसान है कि मैं के साथ अटक गया हो सकता है?
12 '14

6
यह मेरे लिए काम कर रहा है लेकिन एक खोज है। निर्माण के बाद अब दो जार प्रोजेक्ट आर्टिडिड-वर्जन के साथ बनाए गए हैं और दूसरे आर्टिफाइड-वर्जन- "जार-विद-डिपेंडेंसी" के साथ बनाए गए हैं। लेकिन मैं केवल एक जार का निर्माण करना चाहता हूं। क्या कोई और तरीका है
सौविक भट्टाचार्य

38

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

    <plugins>
            <plugin>
                 <artifactId>maven-assembly-plugin</artifactId>
                 <executions>
                     <execution>
                          <phase>package</phase>
                          <goals>
                              <goal>single</goal>
                          </goals>
                      </execution>
                  </executions>
                  <configuration>
                       <!-- ... -->
                       <archive>
                           <manifest>
                                 <mainClass>fully.qualified.MainClass</mainClass>
                           </manifest>
                       </archive>
                       <descriptorRefs>
                           <descriptorRef>jar-with-dependencies</descriptorRef>
                      </descriptorRefs>
                 </configuration>
         </plugin>
   </plugins>

2
क्यों जार का नाम "जार-पर-निर्भरता" द्वारा जोड़ा गया है ?! किसी भी काम?
टीना जे

1
@ टीना जे आप अंतिम नाम में "-जर-के साथ-निर्भरता" प्रत्यय को बाहर करने के <appendAssemblyId>false</appendAssemblyId>लिए <configuration>टैग के अंदर जोड़ सकते हैं ।
ccu

19

वहाँ छाया मावेन प्लगइन है । यह पैकेज और नाम बदलने के लिए इस्तेमाल किया जा सकता है (वर्गपथ पर निर्भरता की समस्याओं को दूर करने के लिए)।


2
अगर आपको फ़ाइल नाम के भाग के रूप में जार-निर्भरताएँ पसंद नहीं हैं।
काइल


यह मेरे लिए सबसे अच्छा जवाब था .. :)
आनंद वर्की फिलिप्स

17

आप एक <classifier>टैग का उपयोग करके नए बनाए गए जार का उपयोग कर सकते हैं ।

<dependencies>
    <dependency>
        <groupId>your.group.id</groupId>
        <artifactId>your.artifact.id</artifactId>
        <version>1.0</version>
        <type>jar</type>
        <classifier>jar-with-dependencies</classifier>
    </dependency>
</dependencies>

14

यदि आप (मेरे जैसे) विशेष रूप से ऊपर वर्णित जार-विद-डिपेंडेंसी अप्रोच को पसंद नहीं करते हैं, तो मेरे द्वारा पसंद किया जाने वाला मावेन-सॉल्यूशन केवल एक WAR- प्रोजेक्ट बनाने के लिए है, भले ही यह केवल एक स्टैंड-अलोन जावा एप्लिकेशन हो जो आप बना रहे हैं:

  1. एक सामान्य मावेन जार-प्रोजेक्ट बनाएं, जो आपकी जार-फ़ाइल (निर्भरता के बिना) का निर्माण करेगा।

  2. इसके अलावा, एक मावेन वॉर-प्रोजेक्ट को सेटअप करें (केवल एक खाली src / main / webapp / WEB-INF / web.xml फ़ाइल के साथ, जो maven-build में चेतावनी / त्रुटि से बच जाएगा), जिसमें केवल आपकी जार-प्रोजेक्ट है एक निर्भरता, और <module>अपने युद्ध-परियोजना के तहत अपने जार-प्रोजेक्ट को बनाएं । (यह युद्ध-परियोजना आपके सभी जार-फ़ाइल निर्भरताओं को ज़िप-फ़ाइल में लपेटने के लिए केवल एक सरल चाल है।)

  3. युद्ध-फाइल बनाने के लिए युद्ध-परियोजना का निर्माण करें।

  4. परिनियोजन-चरण में, अपनी .war-file को * .zip में बदलें और उसे अनज़िप करें।

अब आपके पास एक जार-निर्देशिका होनी चाहिए (जिसे आप स्थानांतरित कर सकते हैं, जहां आप इसे चाहते हैं) अपने जार और उन सभी आश्रितों के साथ जिन्हें आपको अपना आवेदन चलाने की आवश्यकता है:

java -cp 'path/lib/*' MainClass

(Javap-6 या उच्चतर में वर्गपथ में वाइल्डकार्ड काम करता है)

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


क्या यह ग्रहण के समान है "रननेबल जार के रूप में निर्यात करें"? क्योंकि इसके साथ आप "JAR के साथ सभी निर्भरताओं को पैकेज करना" चुन सकते हैं, फिर आपको अपने जार के साथ प्रोजेक्ट-लिबर फ़ोल्डर में सभी निर्भरताएँ मिलती हैं।
पश्चिमीगुण

@FaRR सस्ता - यह "वही" हो सकता है, मैंने कभी कोशिश नहीं की। लेकिन मुझे लगता है कि यदि आप ग्रहण का उपयोग करते हैं, तो यह आसानी से स्क्रिप्ट करने योग्य नहीं है, जो एक आवश्यकता है, यदि आप एक स्वचालित बिल्ड + तैनाती-पाइपलाइन को लागू करना चाहते हैं । उदाहरण के लिए, जेनकिंस-सर्वर आपके गिट स्रोत-रिपॉजिटरी या इसी तरह से बिल्ड करते हैं।
रोप

12

http://fiji.sc/Uber-JAR विकल्पों की एक उत्कृष्ट व्याख्या प्रदान करता है:

एक uber-JAR के निर्माण के तीन सामान्य तरीके हैं:

  1. बेदाग़। सभी JAR फ़ाइलों को अनपैक करें, फिर उन्हें एक JAR में दोहराएं।
    • प्रो: जावा के डिफॉल्ट क्लास लोडर के साथ काम करता है।
    • Con: एक ही पथ (जैसे, मेटा-इन / सेवाओं / javax.script.ScriptEngineFactory) के साथ एकाधिक JAR फ़ाइलों में मौजूद फाइलें एक दूसरे को अधिलेखित कर देंगी, जिसके परिणामस्वरूप दोषपूर्ण व्यवहार होगा।
    • उपकरण: मावेन असेंबली प्लगिन, क्लासरूजर्स उबरजर
  2. छायांकित। समान, लेकिन नाम बदलें (यानी, "शेड") सभी निर्भरता के सभी पैकेजों के समान।
    • प्रो: जावा के डिफॉल्ट क्लास लोडर के साथ काम करता है। कुछ (सभी नहीं) निर्भरता संस्करण झड़पों से बचा जाता है।
    • Con: एक ही पथ (जैसे, मेटा-इन / सेवाओं / javax.script.ScriptEngineFactory) के साथ एकाधिक JAR फ़ाइलों में मौजूद फाइलें एक दूसरे को अधिलेखित कर देंगी, जिसके परिणामस्वरूप दोषपूर्ण व्यवहार होगा।
    • उपकरण: मावेन शेड प्लगिन
  3. जार का जार। अंतिम JAR फाइल में अन्य JAR फाइलें शामिल हैं।
    • प्रो: अवक्षेप निर्भरता संस्करण झड़प। सभी संसाधन फ़ाइलें संरक्षित हैं।
    • Con: जावा को लिपटे JAR फ़ाइलों से कक्षाएं लोड करने के लिए सक्षम करने के लिए एक विशेष "बूटस्ट्रैप" क्लास लोडर बंडल करने की आवश्यकता है। डिबगिंग क्लास लोडर मुद्दे अधिक जटिल हो जाते हैं।
    • उपकरण: ग्रहण जार फ़ाइल निर्यातक, एक-जार।

1
सेवाओं के संबंध में बिल्कुल सच नहीं है, शेड प्लगइन में ट्रांसफॉर्मर हैं और उनमें से एक META-INF/servicesनिर्देशिका के तहत फाइलों की सामग्री को संक्षिप्त करने के लिए है । अधिक जानकारी यहाँ: maven.apache.org/plugins/maven-shade-plugin/examples/…
vitro

7
        <!-- Method 1 -->
        <!-- Copy dependency libraries jar files to a separated LIB folder -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-dependency-plugin</artifactId>
            <configuration>
                <outputDirectory>${project.build.directory}/lib</outputDirectory>
                <excludeTransitive>false</excludeTransitive> 
                <stripVersion>false</stripVersion>
            </configuration>
            <executions>
                <execution>
                    <id>copy-dependencies</id>
                    <phase>package</phase>
                    <goals>
                        <goal>copy-dependencies</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        <!-- Add LIB folder to classPath -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-jar-plugin</artifactId>
            <version>2.4</version>
            <configuration>
                <archive>
                    <manifest>
                        <addClasspath>true</addClasspath>
                        <classpathPrefix>lib/</classpathPrefix>
                    </manifest>
                </archive>
            </configuration>
        </plugin>


        <!-- Method 2 -->
        <!-- Package all libraries classes into one runnable jar -->
        <plugin>
            <artifactId>maven-assembly-plugin</artifactId>
            <executions>
              <execution>
                <phase>package</phase>
                <goals>
                  <goal>single</goal>
                </goals>
              </execution>
            </executions>
            <configuration>
              <descriptorRefs>
                <descriptorRef>jar-with-dependencies</descriptorRef>
              </descriptorRefs>
            </configuration>
        </plugin>            

4

Eclipse Luna और m2eclipse पर मेरा निश्चित समाधान: कस्टम क्लास लोडर (डाउनलोड करें और अपनी परियोजना में जोड़ें, केवल 5 कक्षाएं): http://git.eclipse.org/c/jdt/eclipse.jdt.ui/plain/org। eclipse.jdt.ui / jar% 20in% 20jar% 20loader / org / ग्रहण / jdt / आंतरिक / jarinjarloader / ; यह क्लास-लोडर एक-जार क्लास-लोडर से बहुत अच्छा है और बहुत तेज़ है;

<project.mainClass>org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader</project.mainClass> <project.realMainClass>my.Class</project.realMainClass>

JIJConstants "Rsrc-Class-Path" में "Class-Path"
mvan साफ-सुथरी निर्भरता में संपादित करें : प्रतिलिपि-निर्भरता पैकेज
एक पतला क्लास-लोडर के साथ lib फ़ोल्डर में निर्भरता वाला जार बनाया गया है

<build>
    <resources>
        <resource>
            <directory>src/main/java</directory>
            <includes>
                <include>**/*.java</include>
                <include>**/*.properties</include>
            </includes>
        </resource>
        <resource>
            <directory>src/main/resources</directory>
            <filtering>true</filtering>
            <includes>
                <include>**/*</include>
            </includes>
            <targetPath>META-INF/</targetPath>
        </resource>
        <resource>
            <directory>${project.build.directory}/dependency/</directory>
            <includes>
                <include>*.jar</include>
            </includes>
            <targetPath>lib/</targetPath>
        </resource>
    </resources>
<pluginManagement>
        <plugins>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-jar-plugin</artifactId>
                <configuration>
                    <archive>
                        <manifest>
                            <addClasspath>true</addClasspath>
                            <mainClass>${project.mainClass}</mainClass>
                            <classpathPrefix>lib/</classpathPrefix>
                        </manifest>

                        <manifestEntries>
                            <Rsrc-Main-Class>${project.realMainClass}  </Rsrc-Main-Class>
                            <Class-Path>./</Class-Path>
                        </manifestEntries>

                    </archive>
                </configuration>
            </plugin>
<plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-dependency-plugin</artifactId>
                <executions>
                    <execution>
                        <id>copy-dependencies</id>
                        <phase>package</phase>
                        <goals>
                            <goal>copy-dependencies</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </pluginManagement>
</build>

मावेन-निर्भरता-प्लगइन <outputDirectory> काम न करें, हमेशा "निर्भरता" फ़ोल्डर पर लिखें
Glaucio Southier

एक आंतरिक फ़ोल्डर "निर्भरता" के साथ एक जार बनाएं जिसमें प्रोजेक्ट निर्भरताएं हों और इसे MANIFEST.MF पर डाल दें
Glaucio Southier

<संसाधन> <संसाधन> <निर्देशिका> src / main / java </ निर्देशिका> <शामिल है> <शामिल> ** / *। जावा </ शामिल> <शामिल> ** / *। गुण </ शामिल> </ शामिल हैं। > </ संसाधन> <संसाधन> <निर्देशिका> src / मुख्य / संसाधन </ निर्देशिका> <फ़िल्टरिंग> सत्य </ फ़िल्टरिंग> <शामिल> <शामिल> ** / * </ शामिल> </ शामिल> <लक्ष्यपा> मेटा -INF / </ targetPath> </ संसाधन> <संसाधन> <निर्देशिका> $ {project.build.directory} / निर्भरता / </ निर्देशिका> <शामिल> <शामिल> * जार </ शामिल> </ शामिल> <। targetPath> lib / </ targetPath> </ संसाधन> </ संसाधन>
Glaucio Southier

1
इस जवाब के आधार पर मैंने यह प्रोजेक्ट बनाया। आपको pom फ़ाइल को छोड़कर कुछ भी बदलने की आवश्यकता नहीं है: github.com/raisercostin/jarinjarloader
raisercostin

1

मावेन को एक तरफ रखकर, आप जार जार को मेन जार के अंदर रख सकते हैं लेकिन आपको अपने स्वयं के क्लास लोडर का उपयोग करने की आवश्यकता होगी।

इस प्रोजेक्ट की जाँच करें: One-JAR लिंक टेक्स्ट


वहाँ भी एक-जार के लिए एक Maven प्लगइन है: onejar-maven-plugin.googlecode.com/svn/mavensite/usage.html
थिलो

0

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

अंत में, आवेदन शुरू करने में सक्षम नहीं था क्योंकि वसंत जार सही गुण फाइलों को नहीं पा सके। इस मामले में रोप द्वारा प्रस्तावित प्रस्ताव ने मेरी समस्या को हल कर दिया है।

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


0

इस जवाब पर एक नजर:

मैं एक इंस्टॉलर बना रहा हूं जो जावा जार फाइल के रूप में चलता है और इसे इंस्टॉलेशन डायरेक्टरी में WAR और JAR फाइलों को उपयुक्त स्थानों पर अनपैक करने की जरूरत है। निर्भरता प्लगइन को कॉपी लक्ष्य के साथ पैकेज चरण में इस्तेमाल किया जा सकता है और यह मावेन रिपॉजिटरी (डब्ल्यूएआर फाइलों सहित) में किसी भी फाइल को डाउनलोड करेगा और उन्हें लिखेगा जहां कभी भी आपको उनकी आवश्यकता होगी। मैंने आउटपुट निर्देशिका को $ {project.build.directory} / कक्षाओं में बदल दिया और फिर अंतिम परिणाम यह है कि सामान्य JAR कार्य में मेरी फ़ाइलें ठीक शामिल हैं। मैं तब उन्हें निकाल सकता हूं और उन्हें इंस्टॉलेशन डायरेक्टरी में लिख सकता हूं।

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
    <execution>
        <id>getWar</id>
        <phase>package</phase>
        <goals>
            <goal>copy</goal>
        </goals>
        <configuration>
            <artifactItems>
                <artifactItem>
                    <groupId>the.group.I.use</groupId>
                    <artifactId>MyServerServer</artifactId>
                    <version>${env.JAVA_SERVER_REL_VER}</version>
                    <type>war</type>
                    <destFileName>myWar.war</destFileName>
                </artifactItem>
            </artifactItems>
            <outputDirectory>${project.build.directory}/classes</outputDirectory>
        </configuration>
    </execution>
</executions>


0

धन्यवाद मैंने POM.xml फ़ाइल में Mippet के नीचे जोड़ा है और Mp समस्या हल हो गई है और सभी जार जार में वसा जार फ़ाइल बनाएँ।

<plugin>
    <artifactId>maven-assembly-plugin</artifactId>
        <executions>
            <execution>
                <phase>package</phase>
                <goals>
                    <goal>single</goal>
                </goals>
            </execution>
        </executions>
        <configuration>
            <descriptorRefs>
                <descriptorRef>dependencies</descriptorRef>
            </descriptorRefs>
        </configuration>
    </plugin>
</plugins>
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.