Projemi dağıtım için tek bir yürütülebilir JAR içinde paketlemek istiyorum.
Bir Maven proje paketini tüm bağımlılık JAR'larını çıktı JAR'ma nasıl yapabilirim?
Projemi dağıtım için tek bir yürütülebilir JAR içinde paketlemek istiyorum.
Bir Maven proje paketini tüm bağımlılık JAR'larını çıktı JAR'ma nasıl yapabilirim?
Yanıtlar:
<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 onunla koşuyorsun
mvn clean compile assembly:single
Derleme hedefi montajdan önce eklenmelidir: tek veya başka bir şekilde kendi projenizdeki kod dahil değildir.
Yorumlarda daha fazla ayrıntı görün.
Genellikle bu hedef otomatik olarak yürütmek için bir oluşturma aşamasına bağlıdır. Bu, mvn install
bir dağıtım / yayın yürütürken veya gerçekleştirirken JAR'ın oluşturulmasını sağlar .
<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>
mvn clean compile assembly:single
.
<appendAssemblyId>false</appendAssemblyId>
içine ekleyebilirsinizconfiguration
compile
ve mahvoldun.
Bağımlılık eklentisini, paket aşamasından önce ayrı bir dizinde tüm bağımlılıkları oluşturmak için kullanın ve ardından bunu manifest sınıf yoluna dahil edin:
<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 ${project.build.directory}/classes/lib
olarak, tüm jar dosyalarını ana kavanoza entegre etmek için OutputDirectory olarak kullanın , ancak kavanozları yüklemek için özel sınıf yükleme kodu eklemeniz gerekecektir.
${project.build.directory}/classes/lib
olarak outputDirectory
içindeki tüm bağımlılıkları ile bir ana .jar olması, ancak - Bu nasıl kavanoz yüklemek için özel classloading kodu eklemek? Ben gibi iş yürütme yapmak gerekir: java -jar main-jar-with-deps.jar
. Mümkün mü ?
Bunu yapmanın farklı yolları hakkında blog yazdım.
Bkz. Apache Maven ile Yürütülebilir Kavanoz (WordPress)
veya maven-ile-çalıştırılabilir-jar (GitHub)
Bu artıları ve eksileri Stephan tarafından sağlanır .
<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>
<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 sınıfyolu elemanları ile çalıştırılabilir.
$ java -jar target/${project.build.finalName}.jar
jar
Dosya kardeş ile sadece çalıştırılabilir olduğu ...lib/
dizine. Dizin ve içeriği ile dağıtmak için arşivler yapmalıyız.
<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 target/${project.build.finalName}.(zip|tar|tar.bz2|tar.gz)
her biri jar
ve içerir lib/*
.
<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
.
<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
.
<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>
<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
.
Cevaplanmamış yanıtını alıp yeniden biçimlendirdiğimizde:
<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 çağrılacak bir şey yerine, yapınızın doğal bir parçası haline getirmenizi tavsiye ederim. Bunu yapınızın ayrılmaz bir parçası yapmak için, bu eklentiyi kendinize ekleyin pom.xml
ve package
yaşam döngüsü etkinliğine bağlayın. Bununla birlikte, bir gotcha, assembly:single
pom.xml dosyasına koyarsanız, komut satırından manuel olarak çalıştırıyorsanız 'assembly: assembly' olarak adlandırırken hedefi çağırmanız gerektiğidir .
<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>
Tüm bağımlılıkları bir uber-jar içine paketlemek için maven-shade-plugin kullanın. Ana sınıfı belirterek yürütülebilir bir kavanoz oluşturmak için de kullanılabilir. Maven-montaj ve maven-jar kullanmaya çalıştıktan sonra, bu eklentinin ihtiyaçlarıma en uygun olduğunu buldum.
Bu eklentinin üzerine yazmak yerine belirli dosyaların içeriğini birleştirdiği için özellikle 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>
Uzun zamandır maven montaj eklentisini kullandım , ancak soruna bir çözüm bulamadım "already added, skipping"
. Şimdi, başka bir eklenti kullanıyorum - onejar-maven-plugin . Aşağıdaki örnek ( mvn package
yapı kavanozu):
<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 gerekir:
<pluginRepositories>
<pluginRepository>
<id>onejar-maven-plugin.googlecode.com</id>
<url>http://onejar-maven-plugin.googlecode.com/svn/mavenrepo</url>
</pluginRepository>
</pluginRepositories>
Maven-dependsency-plugin kullanabilirsiniz, ancak soru yürütülebilir bir JAR'ın nasıl oluşturulacağıydı. Bunu yapmak için Matthew Franglen'in yanıtında aşağıdaki değişiklik yapılmasını gerektirir (btw, bağımlılık eklentisini kullanmak temiz bir hedeften başlarken 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>
Aşağıdaki gibi bir uber kavanozu oluşturmak için maven-shade eklentisini kullanabilirsiniz
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
</plugin>
Sonuçta elde edilen tek JAR'ınızdaki diğer JAR içeriklerini gerçekten yeniden paketlemek istiyorsanız başka bir seçenek Maven Assembly eklentisidir . Paketten çıkarır ve ardından her şeyi bir dizine yeniden paketler <unpack>true</unpack>
. Sonra onu devasa bir JAR'a dönüştüren ikinci bir pasınız olacaktı.
Başka bir seçenek OneJar eklentisidir . Bu, yukarıdaki yeniden paketleme işlemlerini tek bir adımda gerçekleştirir.
Pom.xml dosyanıza aşağıdakileri ekleyebilirsiniz :
<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 konsoldan pom.xml dosyasının bulunduğu dizine geçmeniz gerekir. Sonra mvn assembly: single yürütmek zorunda ve sonra bağımlılıkları ile yürütülebilir JAR dosya umarım inşa edilecektir. Cd ./target ile output (target) dizinine geçerken ve jar'nizi java -jar mavenproject1-1.0-SNAPSHOT-jar-depends-jar.jar benzeri bir komutla başlatırken kontrol edebilirsiniz .
Bunu Apache Maven 3.0.3 ile test ettim .
Tüm bağımlılıkları içeren şişman yürütülebilir bir kavanoz yapmak isteyen bu yanıtların her birini geçtim ve hiçbiri doğru çalışmadı. Cevap gölge eklentisidir, çok kolay ve anlaşılır.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.3</version>
<executions>
<!-- Run shade goal on package phase -->
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>path.to.MainClass</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
Bunun düzgün çalışması için bağımlılıklarınızın bir derleme veya çalışma zamanı kapsamına sahip olması gerektiğini unutmayın.
plugin
Eleman gider pom.xml
under build/plugins
.
Sen birleştirmek olabilir maven-shade-plugin
ve maven-jar-plugin
.
maven-shade-plugin
Tek bir kavanoz dosyada sınıfları ve tüm bağımlılıklarını paketleri.maven-jar-plugin
Yürütülebilir kavanozunuzun ana sınıfını belirtmek için yapılandırın (bkz . Sınıf Yolunu Ayarlama , "Kavanozu Çalıştırılabilir Yapma" bölümü).Şunun için örnek POM yapılandırması maven-jar-plugin
:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>com.example.MyMainClass</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
Son olarak çalıştırılabilir kavanozu çağırarak oluşturun:
mvn clean package shade:shade
Bana göre Ken Liu var. Maven bağımlılık eklentisi, daha sonra kaynak olarak değerlendirebileceğiniz tüm bağımlılıkları genişletmenize izin verir. Bu onları ana yapıya dahil etmenizi sağlar . Montaj eklentisinin kullanımı, değiştirilmesi zor olan ikincil bir eser oluşturur - benim durumumda özel manifest girişleri eklemek istedim. Benim pom sona erdi:
<project>
...
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<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>
<targetPath>/</targetPath>
</resource>
</resources>
</build>
...
</project>
Böyle olmalı:
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>unpack-dependencies</id>
<phase>generate-resources</phase>
<goals>
<goal>unpack-dependencies</goal>
</goals>
</execution>
</executions>
</plugin>
Paketten çıkarma, kaynak üretme aşamasında olmalıdır, çünkü paket aşamasındaysa kaynak olarak dahil edilmez. Temiz paketi deneyin ve göreceksiniz.
Maven-assembly-plugin-2.2.1 ile paylaşılan derleme dosyasını bulma konusunda sorun mu yaşıyorsunuz?
Descriptor / descriptor veya descriptorRefs / descriptorRef parametreleri yerine descriptorId yapılandırma parametresini kullanmayı deneyin.
İkisi de ihtiyacınız olanı yapmaz: dosyayı sınıf yolunda arayın. Tabii ki, paylaşılan montajın maven-assembly-plugin sınıf yolunda bulunduğu paketi eklemeniz gerekir (aşağıya bakın). Maven 2.x kullanıyorsanız (Maven 3.x değil), pluginManagement bölümünde bu bağımlılığı en üstteki üst pom.xml dosyasına eklemeniz gerekebilir.
Bkz bu fazla ayrıntı için.
Sınıf: org.apache.maven.plugin.assembly.io.DefaultAssemblyReader
Misal:
<!-- Use the assembly plugin to create a zip file of all our dependencies. -->
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.2.1</version>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<descriptorId>assembly-zip-for-wid</descriptorId>
</configuration>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>cz.ness.ct.ip.assemblies</groupId>
<artifactId>TEST_SharedAssemblyDescriptor</artifactId>
<version>1.0.0-SNAPSHOT</version>
</dependency>
</dependencies>
</plugin>
Bu sorunu çözmek için, bağımlı JAR'ları ile birlikte JAR'ı tek bir yürütülebilir JAR dosyasına oluşturacak Maven Assembly Eklentisini kullanacağız. Pom.xml dosyanıza aşağıdaki eklenti yapılandırmasını eklemeniz yeterlidir.
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>com.your.package.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>
</pluginManagement>
</build>
Bunu yaptıktan sonra MAVEN aracını bu komutla çalıştırmayı unutmayın mvn clean compile assembly: single
Soruyu doğrudan daha önce yapmış olduğu gibi doğrudan cevaplamayacağım, ancak tüm bağımlılıkları projenin kavanozuna yerleştirmenin iyi bir fikir olup olmadığını gerçekten merak ediyorum.
Bu noktayı görüyorum (konuşlandırma / kullanım kolaylığı) ancak bu, teklifinizin kullanım durumuna bağlıdır (ve alternatifler olabilir (aşağıya bakınız)).
Tamamen bağımsız kullanıyorsanız, neden olmasın.
Ancak projenizi başka bağlamlarda kullanırsanız (bir web uygulamasında olduğu gibi veya diğer kavanozların oturduğu bir klasöre bırakılırsanız), sınıf yolunuzda (klasördekiler, kavanozlardaki olanlar) kavanoz kopyalarınız olabilir. Belki bir teklif anlaşma değil ama ben genellikle bu kaçının.
İyi bir alternatif:
Bunun gibi, sonunda sadece bir manifest ve bir "özel dinamik sınıf yükleyici ana" ile projenize aşağıdakilerle başlayabilirsiniz:
java -jar ProjectMainJar.jar com.stackoverflow.projectName.MainDynamicClassLoaderClass
Komut satırından yürütülebilir bir JAR oluşturmak için proje yolundan aşağıdaki komutu çalıştırın:
mvn assembly:assembly
pom.xml
başka şeyler yapman gerekiyor Error reading assemblies: No assembly descriptors found.
. Zaten benim için olan da bu.
Bu bulduğum en iyi yol:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.4</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>com.myDomain.etc.MainClassName</mainClass>
<classpathPrefix>dependency-jars/</classpathPrefix>
</manifest>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.5.1</version>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>
${project.build.directory}/dependency-jars/
</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
Bu yapılandırmada, tüm bağımlılıklar yer alacaktır /dependency-jars
. Uygulamamın hiçbir Main
sınıfı yok , sadece bağlam olanları var, ama bağımlılıklarımdan birinde JMX sunucusunu başlatan ve bir veya parametre alan bir Main
class ( com.myDomain.etc.MainClassName
) var . Yani bu ile benim uygulama böyle başlamayı başardı:start
stop
java -jar ./lib/TestApp-1.0-SNAPSHOT.jar start
Hepiniz için yararlı olmasını bekliyorum.
Bu yazıda bahsedilen ağaç eklentilerini karşılaştırdım. 2 kavanoz ve tüm kavanozları içeren bir dizin hazırladım. Sonuçları karşılaştırdım ve kesinlikle maven-gölge eklentisi en iyisi. Zorluğum, birleştirilmesi gereken birden fazla kaynak kaynağının yanı sıra jax-r'ler ve JDBC hizmetlerine sahip olmamdı. Hepsi, maven-montaj-eklentisine kıyasla gölge eklentisi tarafından düzgün bir şekilde birleştirildi. Bu durumda yay, kendi kaynaklar klasörünüze kopyalayıp elle bir kez birleştirmediğiniz sürece başarısız olur. Her iki eklenti de doğru bağımlılık ağacını çıkarır. Test, sağlama, derleme vb.Gibi birden çok kapsam vardı ve sağlanan ve her iki eklenti tarafından atlandı. Her ikisi de aynı tezahürü üretti, ancak transformatörlerini kullanarak lisansları gölge eklentisi ile birleştirebildim. Maven-bağımlılık-eklentisi ile elbette t Bu problemlere sahip değilsiniz çünkü kavanozlar çıkarılmıyor. Ancak bazılarının işaret ettiği gibi, düzgün çalışmak için bir ekstra dosya taşımanız gerekir. İşte pom.xml'den bir ekran alıntısı
<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>
<includeScope>compile</includeScope>
<excludeTransitive>true</excludeTransitive>
<overWriteReleases>false</overWriteReleases>
<overWriteSnapshots>false</overWriteSnapshots>
<overWriteIfNewer>true</overWriteIfNewer>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.6</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>com.rbccm.itf.cdd.poller.landingzone.LandingZonePoller</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>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.4.3</version>
<configuration>
<shadedArtifactAttached>false</shadedArtifactAttached>
<keepDependenciesWithProvidedScope>false</keepDependenciesWithProvidedScope>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/services/javax.ws.rs.ext.Providers</resource>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/spring.factories</resource>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/spring.handlers</resource>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/spring.schemas</resource>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/spring.tooling</resource>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"/>
<transformer implementation="org.apache.maven.plugins.shade.resource.ApacheLicenseResourceTransformer">
</transformer>
</transformers>
</configuration>
<executions>
<execution>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
</plugin>
Benim için işe yarayan bir şey:
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>unpack-dependencies</id>
<phase>prepare-package</phase>
<goals>
<goal>unpack-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/classes</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<executions>
<execution>
<id>unpack-dependencies</id>
<phase>package</phase>
</execution>
</executions>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
<mainClass>SimpleKeyLogger</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
Olağandışı bir durumum vardı çünkü bağımlılığım sistem biriydi:
<dependency>
..
<scope>system</scope>
<systemPath>${project.basedir}/lib/myjar.jar</systemPath>
</dependency>
@ User189057 tarafından sağlanan kod değişikliklerle değiştirdim: 1) maven-bağımlılık-eklentisi "hazırlama-paketi" faz 2 yürütülür) Ben doğrudan "hedef / sınıflar" paketsiz classess ayıklanıyor
Burada en çok oylanan yanıtı denedim ve kavanozu çalıştırılabilir hale getirdim. Ancak program düzgün çalışmadı. Sebebin ne olduğunu bilmiyorum. Çalıştırmaya çalıştığımda Eclipse
, farklı bir sonuç alıyorum ama kavanozu komut satırından çalıştırdığımda farklı bir sonuç alıyorum (programa özgü bir çalışma zamanı hatasıyla kilitleniyor).
Projem için çok fazla (Maven) bağımlılığım olduğu için OP ile benzer bir gereksinimim vardı. Neyse ki, benim için işe yarayan tek çözüm kullanmaktı Eclipse
. Çok basit ve çok açık. Bu OP için bir çözüm değil, benzer bir şartı olan ancak birçok Maven bağımlılığı olan biri için bir çözümdür,
1) Proje klasörünüze sağ tıklayın (Eclipse'de) ve Export
2) Ardından Java
->Runnable Jar
3) Kavanoz dosyasının yerini seçmeniz istenecektir
4) Son olarak, çalıştırmak istediğiniz Main yöntemine sahip sınıfı seçin ve seçin Package dependencies with the Jar file
veFinish
Bu da bir seçenek olabilir, jar dosyanızı oluşturabileceksiniz
<build>
<plugins>
<plugin>
<!-- Build an executable JAR -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.4</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
<mainClass>WordListDriver</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</build>
Belirli bağımlılıkları uber-jar'dan hariç tutma seçenekleri arayan herkes için, bu benim için çalışan bir çözümdür:
<project...>
<dependencies>
<dependency>
<groupId>org.apache.spark</groupId>
<artifactId>spark-core_2.11</artifactId>
<version>1.6.1</version>
<scope>provided</scope> <=============
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<archive>
<manifest>
<mainClass>...</mainClass>
</manifest>
</archive>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Yani mvn-assembly-eklentisinin bir konfigürasyonu değil, bağımlılığın bir özelliği.
Şimdiden milyonlarca cevap var, <mainClass>
uygulamanıza inputPoint eklemeniz gerekmiyorsa eklemek istemiyorum. Örneğin, API'lerin mutlaka main
yöntemi olmayabilir .
<build>
<finalName>log-enrichment</finalName>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</plugin>
</plugins>
</build>
mvn clean compile assembly:single
ll target/
total 35100
drwxrwx--- 1 root vboxsf 4096 Sep 29 16:25 ./
drwxrwx--- 1 root vboxsf 4096 Sep 29 16:25 ../
drwxrwx--- 1 root vboxsf 0 Sep 29 16:08 archive-tmp/
drwxrwx--- 1 root vboxsf 0 Sep 29 16:25 classes/
drwxrwx--- 1 root vboxsf 0 Sep 29 16:25 generated-sources/
drwxrwx--- 1 root vboxsf 0 Sep 29 16:25 generated-test-sources/
-rwxrwx--- 1 root vboxsf 35929841 Sep 29 16:10 log-enrichment-jar-with-dependencies.jar*
drwxrwx--- 1 root vboxsf 0 Sep 29 16:08 maven-status/
Pom.xml dosyasına ekle:
<dependency>
<groupId>com.jolira</groupId>
<artifactId>onejar-maven-plugin</artifactId>
<version>1.4.4</version>
</dependency>
ve
<plugin>
<groupId>com.jolira</groupId>
<artifactId>onejar-maven-plugin</artifactId>
<version>1.4.4</version>
<executions>
<execution>
<goals>
<goal>one-jar</goal>
</goals>
</execution>
</executions>
</plugin>
Bu kadar. Sonraki mvn paketi ayrıca tüm bağımlılık kavanozları da dahil olmak üzere ek olarak bir yağ kavanozu oluşturacaktır.
Maaven-montaj-eklentisi benim için harika çalıştı. Maven-bağımlılık eklentisi ile saat geçirdim ve çalıştıramadım. Bunun ana nedeni, yapılandırma bölümünde açıkça dokümantasyonda açıklandığı gibi eklenmesi gereken yapay öğeler tanımlamam gerekti . Kullanmak istediğiniz durumlar için bir örnek var: mvn dependency:copy
herhangi bir artifactItems içermeyen ancak çalışmıyor.
Bu blog yazısı, maven-jar ve maven-assembly eklentilerini birleştirmeyle ilgili başka bir yaklaşımı göstermektedir. Blog gönderisindeki montaj yapılandırması xml ile, bağımlılıkların genişletilip genişletilmeyeceği veya sadece bir klasörde toplanıp manifest'teki bir sınıf yolu girişi tarafından referans verileceği kontrol edilebilir:
İdeal çözüm, kavanozları bir lib klasörüne dahil etmektir ve ana kavanozun manifest.mf dosyası, sınıf yolundaki tüm kavanozları içerir.
Ve tam olarak burada açıklanmıştır: https://caffebig.wordpress.com/2013/04/05/executable-jar-file-with-dependent-jars-using-maven/
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.4.1</version>
<configuration>
<!-- get all project dependencies -->
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<!-- bind to the packaging phase -->
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
Tamam, bu benim çözümüm. Pom.xml dosyasını kullanmadığını biliyorum. Ama Netbeans üzerinde derleme ve çalışan benim programmme sorun vardı ama Java -jar MyJarFile.jar denediğimde başarısız oldu. Şimdi, Maven'i tam olarak anlamıyorum ve bu yüzden Netbeans 8.0.2'yi jar dosyamı bir kavanoz dosyasına koymak için bir kütüphaneye dahil etmekte sorun yaşıyorum. Eclipse'de Maven olmadan jar dosyalarını nasıl kullandığımı düşünüyordum.
Tüm bağımlılıkları ve eklentileri derleyebilen Maven. Netbeans değil. (Netbeans alabiliyorsanız ve bunu yapmak için java .jar kullanabiliyorsanız lütfen bana nasıl söyleyin (^. ^) V)
[Çözüldü - Linux için] bir terminal açarak.
Sonra
cd /MyRootDirectoryForMyProject
Sonraki
mvn org.apache.maven.plugins:maven-compiler-plugin:compile
Sonraki
mvn install
Bu, hedef dizinde jar dosyası oluşturur.
MyJarFile-1.0-jar-with-dependencies.jar
şimdi
cd target
(Sen çalıştırmanız gerekebilir: chmod +x MyJarFile-1.0-jar-with-dependencies.jar
)
Ve sonunda
java -jar MyJarFile-1.0-jar-with-dependencies.jar
Bakınız
https://cwiki.apache.org/confluence/display/MAVEN/LifecyclePhaseNotFoundException
Bu çözümü benzer bir sorunu olan diğer birkaç sayfada yayınlayacağım. Umarım birini bir hafta hayal kırıklığından kurtarabilirim.