Soru Maven kullanarak bağımlılıkları olan bir yürütülebilir JAR'ı nasıl oluşturabilirim?


Projemi dağıtım için tek bir yürütülebilir JAR'da paketlemek istiyorum.

Bir Maven proje paketini JAR'ları çıkışım JAR'a nasıl yükleyebilirim?


1944
2018-02-22 08:43


Menşei


Lütfen bağımlılık eklentisinin hangi hedefine başvurduğunuzu açıklayın. Asıl soruların ne istediğini yapan hiçbir amaç bilmiyorum: A bağımlılarının tümünü A) yazarlarının kavanozlarına yeniden paketleme yoluyla koymak ya da B) MANIFEST.MF sınıfında başkalarına sahip olan çalıştırılabilir bir jar oluşturmak - Matthew McCullough
Bunu yararlı bulabilirsin rationaljava.com/2015/02/... - Dan
2 örnek: tugay.biz/2015/12/a-standalone-java-web-application-with.html  tugay.biz/2016/11/how-did-i-create-executable-jar-with.html - Koray Tugay
başvurmak stackoverflow.com/questions/35217128/... - Thanga


Cevaplar:


<build>
  <plugins>
    <plugin>
      <artifactId>maven-assembly-plugin</artifactId>
      <configuration>
        <archive>
          <manifest>
            <mainClass>fully.qualified.MainClass</mainClass>
          </manifest>
        </archive>
        <descriptorRefs>
          <descriptorRef>jar-with-dependencies</descriptorRef>
        </descriptorRefs>
      </configuration>
    </plugin>
  </plugins>
</build>

ve sen onu çalıştır

mvn clean compile assembly:single

Derleme amacı, derleme öncesinde eklenmelidir: tek veya başka bir şekilde kendi projenizdeki kod dahil değildir.

Yorumlarda daha fazla ayrıntıya bakın.


Genellikle bu amaç otomatik olarak yürütmek için bir yapı aşamasına bağlanır. Bu, JAR'ın yürütülürken oluşturulmasını sağlar mvn install veya bir dağıtım / yayın gerçekleştirme.

<plugin>
  <artifactId>maven-assembly-plugin</artifactId>
  <configuration>
    <archive>
      <manifest>
        <mainClass>fully.qualified.MainClass</mainClass>
      </manifest>
    </archive>
    <descriptorRefs>
      <descriptorRef>jar-with-dependencies</descriptorRef>
    </descriptorRefs>
  </configuration>
  <executions>
    <execution>
      <id>make-assembly</id> <!-- this is used for inheritance merges -->
      <phase>package</phase> <!-- bind to the packaging phase -->
      <goals>
        <goal>single</goal>
      </goals>
    </execution>
  </executions>
</plugin>

1866
2017-12-01 10:46



Teşekkürler @IAdapter. JAR'da her zaman "hedef / sınıflar" içinde yer alan her şeyi koyacağından, her zaman bir derlemeden önce derlemeniz gerektiğini unutmayın. Bu, JAR'ın son zamanlarda kaynak kodda yaptığınız tüm değişiklikleri içermesini sağlayacaktır. Yani, şöyle bir şey yapmalısın: mvn clean compile assembly:single. - Michael
Faz bağını dahil etmek için soruyu düzenledim. Kullanımdan kaldırılan montaj hedefini kaldırdım çünkü kimse bunu bilmemeli. - Duncan Jones
Bunun kavanozları kavanozlara eklemediğini görüyorum, bunun yerine tüm sınıf dosyalarını kavanoza ekliyor. - pitchblack408
İpucu: öğeyi de ekleyebilirsiniz <appendAssemblyId>false</appendAssemblyId> içine configuration adında rahatsız edici "-jar-with-dependencies" sonekini önlemek için - maxivis
unutmak compile ve sen batırdın. - prayagupd


Tüm bağımlılıkları paket aşamasından önce ayrı bir dizinde oluşturmak için bağımlılık eklentisini kullanabilir ve ardından bunu manifestin sınıf yoluna dahil edebilirsiniz:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-dependency-plugin</artifactId>
    <executions>
        <execution>
            <id>copy-dependencies</id>
            <phase>prepare-package</phase>
            <goals>
                <goal>copy-dependencies</goal>
            </goals>
            <configuration>
                <outputDirectory>${project.build.directory}/lib</outputDirectory>
                <overWriteReleases>false</overWriteReleases>
                <overWriteSnapshots>false</overWriteSnapshots>
                <overWriteIfNewer>true</overWriteIfNewer>
            </configuration>
        </execution>
    </executions>
</plugin>
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-jar-plugin</artifactId>
    <configuration>
        <archive>
            <manifest>
                <addClasspath>true</addClasspath>
                <classpathPrefix>lib/</classpathPrefix>
                <mainClass>theMainClass</mainClass>
            </manifest>
        </archive>
    </configuration>
</plugin>

Alternatif olarak ${project.build.directory}/classes/lib Tüm jar dosyalarını ana jarte entegre etmek için OutputDirectory olarak, ancak daha sonra kavanozları yüklemek için özel classloading kodunu eklemeniz gerekir.


294
2018-06-02 03:01



+1 Mükemmel. Maven-assembly-plugin yerine maven-bağımlılık-plugin ile devam etmemin nedeni de buildnumber-maven-plugin kullanıyorum ve bu şekilde her bir kavanozun manifestinde versiyon numarasını ayrı ayrı saklayabiliyorum. - PapaFreud
Çözümü beğendim. kullanırım ${project.build.directory}/classes/lib gibi outputDirectory İçinde tüm bağımlılıklar ile bir ana .jar var, ancak - Bu kavanozları yüklemek için özel sınıf kod ekleme nasıl? Çalışmayı şöyle yapmalıyım: java -jar main-jar-with-deps.jar. Mümkün mü ? - marioosh
@ André Aronsen, bu çözümü kullanarak bir lib klasöründeki bağımlılıkları jar içerisine eklemek için kullandım, ama her zaman sınıfta bulunmayan bir istisna alıyorum, lütfen bunu nasıl düzelteceğinizi öğrenebilirsiniz. - Mahmoud Saleh
+ 1 sana! Maven montaj eklentisi 'bağımlılığı olan kavanozlar' gibi görünüyor, gerçekten iyi çalışmıyor. Oluşturulan kavanozda META-INF / spring.schemas bazı girişler eksikti. Bu yüzden, kavanoz-bağımlı-bağımlılıklarını kazıdım ve çözümünüzü yukarıda kullandım. Mükemmel teşekkürler!!! - Derek
Bu sorunla karşılaşan başka biri için, jaru taşıdığınız yerdeki jar ile aynı dizinde lib klasörünü eklemelisiniz. - Sparticles


Bunu yapmak için farklı yollar hakkında blog yazdım.

Görmek Apache Maven ile Yürütülebilir Jar (WordPress)

veya yürütülebilir-kavanoz-ile-maven-, örneğin (GitHub)

notlar

Bu artıları ve eksileri tarafından sağlanır Stephan.


Manuel dağıtım için

  • Artıları
  • Eksileri
    • Bağımlılıklar son kavanozdan çıktı.

Bağımlılıkları belirli bir dizine kopyala

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-dependency-plugin</artifactId>
  <executions>
    <execution>
      <id>copy-dependencies</id>
      <phase>prepare-package</phase>
      <goals>
        <goal>copy-dependencies</goal>
      </goals>
      <configuration>
        <outputDirectory>${project.build.directory}/${project.build.finalName}.lib</outputDirectory>
      </configuration>
    </execution>
  </executions>
</plugin>

Jar Executable ve Classpath Aware yapmak

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

Bu noktada jar aslında harici classpath elemanları ile çalıştırılabilir.

$ java -jar target/${project.build.finalName}.jar

Dağıtılabilir Arşivleri Oluşturun

jar dosya sadece kardeş ile yürütülebilir ...lib/ dizin. Dizini ve içeriğini kullanarak dağıtmak için arşivler yapmamız gerekiyor.

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-antrun-plugin</artifactId>
  <executions>
    <execution>
      <id>antrun-archive</id>
      <phase>package</phase>
      <goals>
        <goal>run</goal>
      </goals>
      <configuration>
        <target>
          <property name="final.name" value="${project.build.directory}/${project.build.finalName}"/>
          <property name="archive.includes" value="${project.build.finalName}.${project.packaging} ${project.build.finalName}.lib/*"/>
          <property name="tar.destfile" value="${final.name}.tar"/>
          <zip basedir="${project.build.directory}" destfile="${final.name}.zip" includes="${archive.includes}" />
          <tar basedir="${project.build.directory}" destfile="${tar.destfile}" includes="${archive.includes}" />
          <gzip src="${tar.destfile}" destfile="${tar.destfile}.gz" />
          <bzip2 src="${tar.destfile}" destfile="${tar.destfile}.bz2" />
        </target>
      </configuration>
    </execution>
  </executions>
</plugin>

Şimdi sahipsin target/${project.build.finalName}.(zip|tar|tar.bz2|tar.gz) her biri içerir jar ve lib/*.


Apache Maven Meclisi Eklentisi

  • Artıları
  • Eksileri
    • Sınıf değiştirme desteği yok (sınıf değişikliği gerekirse maven-shade-plugin kullanın).
<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-assembly-plugin</artifactId>
  <executions>
    <execution>
      <phase>package</phase>
      <goals>
        <goal>single</goal>
      </goals>
      <configuration>
        <archive>
          <manifest>
            <mainClass>${fully.qualified.main.class}</mainClass>
          </manifest>
        </archive>
        <descriptorRefs>
          <descriptorRef>jar-with-dependencies</descriptorRef>
        </descriptorRefs>
      </configuration>
    </execution>
  </executions>
</plugin>

Var target/${project.bulid.finalName}-jar-with-dependencies.jar.


Apache Maven Gölge Eklentisi

  • Artıları
  • Eksileri
<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-shade-plugin</artifactId>
  <executions>
    <execution>
      <goals>
        <goal>shade</goal>
      </goals>
      <configuration>
        <shadedArtifactAttached>true</shadedArtifactAttached>
        <transformers>
          <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
            <mainClass>${fully.qualified.main.class}</mainClass>
          </transformer>
        </transformers>
      </configuration>
    </execution>
  </executions>
</plugin>

Var target/${project.build.finalName}-shaded.jar.


onejar-maven-eklentisi

  • Artıları
  • Eksileri
    • 2012'den beri aktif olarak desteklenmiyor.
<plugin>
  <!--groupId>org.dstovall</groupId--> <!-- not available on the central -->
  <groupId>com.jolira</groupId>
  <artifactId>onejar-maven-plugin</artifactId>
  <executions>
    <execution>
      <configuration>
        <mainClass>${fully.qualified.main.class}</mainClass>
        <attachToBuild>true</attachToBuild>
        <!-- https://code.google.com/p/onejar-maven-plugin/issues/detail?id=8 -->
        <!--classifier>onejar</classifier-->
        <filename>${project.build.finalName}-onejar.${project.packaging}</filename>
      </configuration>
      <goals>
        <goal>one-jar</goal>
      </goals>
    </execution>
  </executions>
</plugin>

Bahar Boot Maven Eklentisi

  • Artıları
  • Eksileri
    • Potansiyel gereksiz Bahar ve İlkbahar Çizme ile ilgili sınıfları ekleyin.
<plugin>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-maven-plugin</artifactId>
  <executions>
    <execution>
      <goals>
        <goal>repackage</goal>
      </goals>
      <configuration>
        <classifier>spring-boot</classifier>
        <mainClass>${fully.qualified.main.class}</mainClass>
      </configuration>
    </execution>
  </executions>
</plugin>

Var target/${project.bulid.finalName}-spring-boot.jar.


134
2018-02-26 04:31



Benim için çalışan tek kişi manuel dağıtımdır. - caiohamamura
@caiohamamura Klonlayabilirsiniz GitHub Deposu ve tüm profillerin nasıl çalıştığını görün. - Jin Kwon
Sorun, kullandığım paket ile oldu: stackoverflow.com/a/12622037/2548351 - caiohamamura


Cevapsız'ın cevabını alarak ve yeniden biçimlendirerek, şunları yaptık:

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-jar-plugin</artifactId>
            <configuration>
                <archive>
                    <manifest>
                        <addClasspath>true</addClasspath>
                        <mainClass>fully.qualified.MainClass</mainClass>
                    </manifest>
                </archive>
            </configuration>
        </plugin>
        <plugin>
            <artifactId>maven-assembly-plugin</artifactId>
            <configuration>
                <descriptorRefs>
                    <descriptorRef>jar-with-dependencies</descriptorRef>
                </descriptorRefs>
            </configuration>
        </plugin>
    </plugins>
</build>

Daha sonra, bunu açıkça adlandırmanız gereken bir şey yerine, yapınızın doğal bir parçası haline getirmenizi öneriyorum. Bunu yapınızın ayrılmaz bir parçası yapmak için, bu eklentiyi pom.xml ve ona bağla package yaşam döngüsü olayı. Ancak, bir gotcha aramak için gereken assembly:single Eğer pom.xml 'inize koyarsanız,' komut: assembly 'komutunu çağırırsanız, bunu komut satırından elle çalıştırırsanız.

<project>
  [...]
  <build>
      <plugins>
          <plugin>
              <artifactId>maven-assembly-plugin</artifactId>
              <configuration>
                  <archive>
                      <manifest>
                          <addClasspath>true</addClasspath>
                          <mainClass>fully.qualified.MainClass</mainClass>
                      </manifest>
                  </archive>
                  <descriptorRefs>
                      <descriptorRef>jar-with-dependencies</descriptorRef>
                  </descriptorRefs>
              </configuration>
              <executions>
                  <execution>
                      <id>make-my-jar-with-dependencies</id>
                      <phase>package</phase>
                      <goals>
                          <goal>single</goal>
                      </goals>
                  </execution>
              </executions>
          </plugin>
      [...]
      </plugins>
    [...]
  </build>
</project>

122
2017-09-22 15:20



Bu yanıttaki yaklaşımı kullanmak aşağıdaki hata iletisiyle sonuçlanır: 'java-jar <jar dosyası>' kullanarak JAR'ı çalıştırmaya çalışırken 'Ana sınıf bildirim özniteliği <jar dosyası>' yüklenemedi. - Elmo
Maven-jar-plugin'in arşiv bölümünün <archive> <manifest> <addClasspath> true </ addClasspath> <mainClass> not.qualified.MainClass </ mainClass> </ manifest> </ arşivi> gereklidir. - RockyMM
Üzgünüz, bu cevap yanlış, mainClass etiketi, paket hedefi sırasında bunu çağıran maven-assembly-plugin girişinde olmalı. - Alex Lehmann
@AlexLehmann gerçek! - RockyMM
Şaşırdım, neden mvn arketipinden sonra pom.xml'nin buna dahil edilemedi? Yeni bir maven projesi oluşturduğumda bunu her zaman el ile kopyalayıp yapıştırmak ... - wintermute


Tüm bağımlılıkları tek bir uber-jar'a paketlemek için maven-shade-plugin kullanın. Ana sınıfı belirterek yürütülebilir bir jar oluşturmak için de kullanılabilir. Maven-assemb ve maven-jar'ı kullanmaya çalıştıktan sonra, bu eklentinin ihtiyaçlarını en iyi şekilde karşıladığını gördüm.

Bu eklentiyi, özellikle üzerine yazmak yerine belirli dosyaların içeriğini birleştirdiği için yararlı buldum. Bu, kavanozlarda aynı ada sahip kaynak dosyaları olduğunda ve eklenti tüm kaynak dosyalarını paketlemeye çalıştığında gereklidir.

Aşağıdaki örneğe bakın

      <plugins>
    <!-- This plugin provides the capability to package the artifact in an uber-jar, including its dependencies and to shade - i.e. rename - the packages of some of the dependencies. -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-shade-plugin</artifactId>
            <version>1.4</version>
            <executions>
                <execution>
                    <phase>package</phase>
                    <goals>
                        <goal>shade</goal>
                    </goals>
                    <configuration>
                        <artifactSet>
                        <!-- signed jars-->
                            <excludes>
                                <exclude>bouncycastle:bcprov-jdk15</exclude>
                            </excludes>
                        </artifactSet>

                         <transformers>
                            <transformer
                                implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                                <!-- Main class -->
                                <mainClass>com.main.MyMainClass</mainClass>
                            </transformer>
                            <!-- Use resource transformers to prevent file overwrites -->
                            <transformer 
                                 implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
                                <resource>properties.properties</resource>
                            </transformer>
                            <transformer
                                implementation="org.apache.maven.plugins.shade.resource.XmlAppendingTransformer">
                                <resource>applicationContext.xml</resource>
                            </transformer>
                            <transformer
                                implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
                                <resource>META-INF/cxf/cxf.extension</resource>
                            </transformer>
                            <transformer
                                implementation="org.apache.maven.plugins.shade.resource.XmlAppendingTransformer">
                                <resource>META-INF/cxf/bus-extensions.xml</resource>
                            </transformer>
                     </transformers>
                    </configuration>
                </execution>
            </executions>
        </plugin>

    </plugins>

91
2018-03-13 20:55



Peki, bcprov-jdk15.jar, çalışma zamanındaki sınıf yoluna nasıl giriyor? - Andrew Swan
Bağımlılığımın bir parçası olan cxf-rt-ws-güvenlik tarafından çekiliyordu. - Vijay Katam
Bu eklentiyi daha önce hiç duymamıştım, ama problemimi kavanozların içindeki spring.handlers ile çözdüm. Teşekkürler! - Alexandre L Telles
Güvenlik istisnası olanlar, DSA'ları Manifest'ten hariç tutuyor. Kontrol maven.apache.org/plugins/maven-shade-plugin/examples/... - ruhsuzbaykus
+1 minijar kullanıyorum: geçmişte ueberjar, ancak minijar eklentisi artık kullanımdan kaldırıldı ve gölge ile değiştirildi - rds


Uzun kullanıldı maven montaj eklentisiama sorunla ilgili bir çözüm bulamadım "already added, skipping". Şimdi başka bir eklenti kullanıyorum - onejar-maven-eklentisi. Aşağıdaki örnek (mvn package kavanoz inşa):

<plugin>
    <groupId>org.dstovall</groupId>
    <artifactId>onejar-maven-plugin</artifactId>
    <version>1.3.0</version>
    <executions>
        <execution>
            <configuration>
                <mainClass>com.company.MainClass</mainClass>
            </configuration>
            <goals>
                <goal>one-jar</goal>
            </goals>
        </execution>
    </executions>
</plugin>

Bu eklenti için depo eklemeniz gerekiyor:

<pluginRepositories>
    <pluginRepository>
        <id>onejar-maven-plugin.googlecode.com</id>
        <url>http://onejar-maven-plugin.googlecode.com/svn/mavenrepo</url>
    </pluginRepository>
</pluginRepositories>

15
2017-10-13 12:16



Çıkışta ekstra mesajlardan nasıl kurtulur? - Alexandr


Maven-bağımlılık-eklentisini kullanabilirsiniz, ancak soru bir JAR nasıl çalıştırılacağıydı. Bunu yapmak için Matthew Franglen'in yanıtında aşağıdaki değişiklik yapılması gerekir (bağımlılık eklentisini kullanan btw, temiz bir hedeften başladığında daha uzun sürer):

<build>
    <plugins>
        <plugin>
            <artifactId>maven-jar-plugin</artifactId>
            <configuration>
                <archive>
                    <manifest>
                        <mainClass>fully.qualified.MainClass</mainClass>
                    </manifest>
                </archive>
            </configuration>
        </plugin>
        <plugin>
            <artifactId>maven-dependency-plugin</artifactId>
            <executions>
                <execution>
                    <id>unpack-dependencies</id>
                    <phase>package</phase>
                    <goals>
                        <goal>unpack-dependencies</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
    <resources>
        <resource>
            <directory>${basedir}/target/dependency</directory>
        </resource>
    </resources>
</build>

14
2018-03-11 15:12





Diğer JAR'ların içeriğini tek bir sonuç JAR içinde yeniden paketlemek istiyorsanız, başka bir seçenek de Maven Meclisi eklentisi. Her şeyi bir dizine paketler ve daha sonra bir dizine aktarır. <unpack>true</unpack>. O zaman bunu büyük bir JAR'a dönüştüren ikinci bir geçişin olacak.

Başka bir seçenek OneJar eklentisidir. Bu, yukarıdaki yeniden paketleme işlemlerini tek adımda gerçekleştirir.


13
2017-08-13 18:23





Aşağıdakileri ekleyebilirsiniz pom.xml:

<build>
<defaultGoal>install</defaultGoal>
<plugins>
  <plugin>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>2.3.2</version>
    <configuration>
      <source>1.6</source>
      <target>1.6</target>
    </configuration>
  </plugin>
  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-jar-plugin</artifactId>
    <version>2.3.1</version>
    <configuration>
      <archive>
        <manifest>
          <addClasspath>true</addClasspath>
          <mainClass>com.mycompany.package.MainClass</mainClass>
        </manifest>
      </archive>
    </configuration>
  </plugin>
  <plugin>
    <artifactId>maven-assembly-plugin</artifactId>
    <configuration>
      <descriptorRefs>
        <descriptorRef>jar-with-dependencies</descriptorRef>
      </descriptorRefs>
      <archive>
        <manifest>
          <mainClass>com.mycompany.package.MainClass</mainClass>
        </manifest>
      </archive>
    </configuration>
    <executions>
      <execution>
        <id>make-my-jar-with-dependencies</id>
        <phase>package</phase>
        <goals>
          <goal>single</goal>
        </goals>
      </execution>
    </executions>
  </plugin>
</plugins>
</build>

Daha sonra, konsol aracılığıyla pom.xml'nin bulunduğu dizine geçmelisiniz. O zaman yürütmek zorundasın. mvn meclisi: tek ve sonra bağımlılıkları olan yürütülebilir JAR dosyanız ümitle inşa edilecektir. İle çıktı (hedef) dizinine geçerken kontrol edebilirsiniz. cd ./target ve kavanoza benzer bir komutla başla java -jar mavenproject1-1.0-SNAPSHOT-jar-with-dependencies.jar.

Bunu test ettim Apache Maven 3.0.3.


11
2017-11-26 14:17