Saya ingin mengemas proyek saya dalam satu JAR yang dapat dieksekusi untuk distribusi.
Bagaimana saya bisa membuat paket proyek Maven semua JAR ketergantungan ke output JAR saya?
Saya ingin mengemas proyek saya dalam satu JAR yang dapat dieksekusi untuk distribusi.
Bagaimana saya bisa membuat paket proyek Maven semua JAR ketergantungan ke output JAR saya?
Jawaban:
<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>
dan Anda menjalankannya
mvn clean compile assembly:single
Kompilasi tujuan harus ditambahkan sebelum perakitan: tunggal atau kode proyek Anda sendiri tidak termasuk.
Lihat lebih detail di komentar.
Biasanya tujuan ini terkait dengan fase pembangunan untuk dijalankan secara otomatis. Ini memastikan JAR dibangun saat menjalankan mvn install
atau melakukan penyebaran / rilis.
<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>
ke dalam configuration
untuk menghindari akhiran "-jar-dengan-dependensi" yang mengganggu dalam nama
compile
dan kamu kacau.
Anda dapat menggunakan dependensi-plugin untuk menghasilkan semua dependensi di direktori terpisah sebelum fase paket dan kemudian memasukkannya ke classpath manifes:
<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>
Atau gunakan ${project.build.directory}/classes/lib
sebagai OutputDirectory untuk mengintegrasikan semua file jar ke jar utama, tetapi kemudian Anda harus menambahkan kode classloading khusus untuk memuat stoples.
${project.build.directory}/classes/lib
sebagai outputDirectory
memiliki satu .jar utama dengan semua dependensi dalam, tapi - Cara menambahkan kode classloading kustom untuk memuat guci ini? Saya perlu membuat pelaksanaan pekerjaan seperti: java -jar main-jar-with-deps.jar
. Apakah ini mungkin?
Saya membuat blog tentang beberapa cara berbeda untuk melakukan ini.
Lihat Jar yang Dapat Dieksekusi dengan Apache Maven (WordPress)
atau executable-jar-with-maven-example (GitHub)
Pro dan kontra itu disediakan oleh Stephan .
<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>
Pada titik jar
ini sebenarnya dapat dieksekusi dengan elemen classpath eksternal.
$ java -jar target/${project.build.finalName}.jar
The jar
file hanya executable dengan saudara ...lib/
direktori. Kita perlu membuat arsip untuk disebarkan dengan direktori dan kontennya.
<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>
Sekarang Anda memiliki target/${project.build.finalName}.(zip|tar|tar.bz2|tar.gz)
yang masing-masing berisi jar
dan 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>
Kamu punya 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>
Kamu punya 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>
Kamu punya target/${project.bulid.finalName}-spring-boot.jar
.
Mengambil jawaban yang Belum Dijawab dan memformatnya kembali, kami memiliki:
<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>
Selanjutnya, saya akan merekomendasikan menjadikan ini bagian alami dari bangunan Anda, daripada sesuatu untuk memanggil secara eksplisit. Untuk menjadikan ini bagian integral dari bangunan Anda, tambahkan plugin ini ke Anda pom.xml
dan ikat ke package
acara siklus hidup. Namun, gotcha adalah bahwa Anda perlu memanggil assembly:single
tujuan jika meletakkan ini di pom.xml Anda, sementara Anda akan memanggil 'assembly: assembly' jika mengeksekusi secara manual dari baris perintah.
<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>
Gunakan maven-shade-plugin untuk mengemas semua dependensi ke dalam satu jar-uber. Ini juga dapat digunakan untuk membangun jar yang dapat dieksekusi dengan menentukan kelas utama. Setelah mencoba menggunakan maven-assembly dan maven-jar, saya menemukan bahwa plugin ini paling sesuai dengan kebutuhan saya.
Saya menemukan plugin ini sangat berguna karena menggabungkan konten file tertentu daripada menimpa mereka. Ini diperlukan ketika ada file sumber daya yang memiliki nama yang sama di seluruh stoples dan plugin mencoba mengemas semua file sumber daya
Lihat contoh di bawah ini
<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>
Lama menggunakan plugin perakitan pakar , tapi saya tidak bisa menemukan solusi untuk masalah dengan "already added, skipping"
. Sekarang, saya menggunakan plugin lain - onejar-maven-plugin . Contoh di bawah ini ( mvn package
build toples):
<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>
Anda perlu menambahkan repositori untuk plugin itu:
<pluginRepositories>
<pluginRepository>
<id>onejar-maven-plugin.googlecode.com</id>
<url>http://onejar-maven-plugin.googlecode.com/svn/mavenrepo</url>
</pluginRepository>
</pluginRepositories>
Anda dapat menggunakan maven-dependency-plugin, tetapi pertanyaannya adalah bagaimana membuat JAR yang dapat dieksekusi. Untuk melakukan itu diperlukan perubahan berikut pada respons Matthew Franglen (btw, menggunakan plugin dependensi lebih lama untuk dibangun ketika mulai dari target bersih):
<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>
Anda dapat menggunakan plugin maven-shade untuk membuat jar uber seperti di bawah ini
<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>
Opsi lain jika Anda benar-benar ingin mengemas kembali isi JAR lain di dalam JAR hasil tunggal Anda adalah plugin Maven Assembly . Itu membongkar dan kemudian mengemas semuanya ke dalam direktori melalui <unpack>true</unpack>
. Maka Anda akan memiliki pass kedua yang membuatnya menjadi satu JAR besar.
Opsi lain adalah plugin OneJar . Ini melakukan tindakan pengemasan ulang di atas semua dalam satu langkah.
Anda dapat menambahkan yang berikut ke pom.xml Anda :
<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>
Setelah itu Anda harus beralih melalui konsol ke direktori, di mana pom.xml berada. Maka Anda harus menjalankan mvn assembly: tunggal dan kemudian file JAR Anda yang dapat dieksekusi dengan dependensi akan dibangun. Anda dapat memeriksanya saat beralih ke direktori keluaran (target) dengan cd ./target dan memulai toples Anda dengan perintah yang serupa dengan java -jar mavenproject1-1.0-SNAPSHOT-jar-with-dependencies.jar .
Saya menguji ini dengan Apache Maven 3.0.3 .
Saya memeriksa setiap respons ini dengan berusaha membuat toples lemak yang bisa dieksekusi berisi semua dependensi dan tidak ada yang berfungsi dengan baik. Jawabannya adalah plugin teduh, sangat mudah dan langsung.
<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>
Perlu diketahui bahwa dependensi Anda perlu memiliki ruang lingkup kompilasi atau runtime agar ini berfungsi dengan baik.
plugin
elemen berjalan di pom.xml
bawah build/plugins
.
Anda dapat menggabungkan maven-shade-plugin
dan maven-jar-plugin
.
maven-shade-plugin
paket kelas dan semua dependensi dalam file jar tunggal.maven-jar-plugin
untuk menentukan kelas utama toples Anda yang dapat dieksekusi (lihat Menyiapkan Classpath , bab "Jadikan Jar Dapat Dieksekusi").Contoh konfigurasi POM untuk 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>
Akhirnya buat jar yang dapat dieksekusi dengan memohon:
mvn clean package shade:shade
Menurut saya, Ken Liu benar. Plugin maven dependency memungkinkan Anda untuk memperluas semua dependensi, yang kemudian dapat Anda perlakukan sebagai sumber daya. Ini memungkinkan Anda untuk memasukkannya dalam artefak utama . Penggunaan plugin rakitan membuat artefak sekunder yang sulit diubah - dalam kasus saya, saya ingin menambahkan entri manifes khusus. Pom saya berakhir sebagai:
<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>
Seharusnya seperti itu:
<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>
Pembongkaran harus dalam fase menghasilkan-sumber daya karena, jika dalam fase paket, tidak akan dimasukkan sebagai sumber daya. Coba paket bersih dan Anda akan melihat.
Ada masalah dengan mencari file assembly bersama dengan maven-assembly-plugin-2.2.1?
Coba gunakan parameter konfigurasi descriptorId daripada parameter deskriptor / descriptor atau descriptorRefs / descriptorRef.
Tak satu pun dari mereka melakukan apa yang Anda butuhkan: mencari file di classpath. Tentu saja Anda perlu menambahkan paket di mana rakitan bersama berada di classpath maven-assembly-plugin (lihat di bawah). Jika Anda menggunakan Maven 2.x (bukan Maven 3.x), Anda mungkin perlu menambahkan ketergantungan ini di pom.xml induk paling atas di bagian pluginManagement.
Lihat ini untuk lebih jelasnya.
Kelas: org.apache.maven.plugin.assembly.io.DefaultAssemblyReader
Contoh:
<!-- 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>
Untuk mengatasi masalah ini kami akan menggunakan Maven Assembly Plugin yang akan membuat JAR bersama dengan JAR ketergantungannya menjadi satu file JAR yang dapat dieksekusi. Cukup tambahkan konfigurasi plugin di bawah ini di file pom.xml Anda.
<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>
Setelah melakukan ini jangan lupa untuk menjalankan alat MAVEN dengan perintah ini mvn clean compile assembly: single
Saya tidak akan menjawab langsung pertanyaan seperti yang sudah dilakukan orang lain sebelumnya, tapi saya benar-benar bertanya-tanya apakah itu ide yang baik untuk menanamkan semua dependensi dalam toples proyek itu sendiri.
Saya melihat intinya (kemudahan penyebaran / penggunaan) tetapi itu tergantung pada kasus penggunaan dari poject Anda (dan mungkin ada alternatif (lihat di bawah)).
Jika Anda menggunakannya sepenuhnya mandiri, mengapa tidak.
Tetapi jika Anda menggunakan proyek Anda dalam konteks lain (seperti di webapp, atau jatuh di folder tempat guci lain), Anda mungkin memiliki duplikat jar di classpath Anda (yang di folder, yang di guci). Mungkin bukan penawaran, tetapi saya biasanya menghindari ini.
Alternatif yang baik:
Seperti ini, dengan pada akhirnya hanya manifes dan "utama classloader dinamis khusus", Anda dapat memulai proyek Anda dengan:
java -jar ProjectMainJar.jar com.stackoverflow.projectName.MainDynamicClassLoaderClass
Untuk membuat JAR yang dapat dieksekusi dari baris perintah itu sendiri, cukup jalankan perintah di bawah ini dari jalur proyek:
mvn assembly:assembly
pom.xml
selain Anda dapatkan Error reading assemblies: No assembly descriptors found.
. Itulah yang terjadi pada saya.
Ini adalah cara terbaik yang saya temukan:
<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>
Dengan konfigurasi ini, semua dependensi akan berlokasi di /dependency-jars
. Aplikasi saya tidak memiliki Main
kelas, hanya konteks, tetapi salah satu dependensi saya memiliki Main
kelas ( com.myDomain.etc.MainClassName
) yang memulai server JMX, dan menerima parameter start
atau stop
. Jadi dengan ini saya dapat memulai aplikasi saya seperti ini:
java -jar ./lib/TestApp-1.0-SNAPSHOT.jar start
Saya tunggu semoga bermanfaat untuk Anda semua.
Saya membandingkan plugin pohon yang disebutkan dalam posting ini. Saya menghasilkan 2 toples dan direktori dengan semua toples. Saya membandingkan hasilnya dan tentu saja maven-shade-plugin adalah yang terbaik. Tantangan saya adalah bahwa saya memiliki banyak sumber daya pegas yang perlu digabung, serta layanan jax-rs, dan JDBC. Mereka semua digabungkan dengan benar oleh plugin warna dibandingkan dengan plugin maven-assembly-plugin. Dalam hal ini pegas akan gagal kecuali Anda menyalinnya ke folder sumber daya Anda sendiri dan menggabungkannya secara manual satu kali. Kedua plugin menghasilkan pohon ketergantungan yang benar. Saya memiliki beberapa ruang lingkup seperti tes, menyediakan, mengkompilasi, dll tes dan disediakan dilewati oleh kedua plugin. Mereka berdua menghasilkan manifes yang sama tetapi saya dapat mengkonsolidasikan lisensi dengan plugin teduh menggunakan transformator mereka. Dengan maven-dependency-plugin tentu saja Anda tidak t memiliki masalah karena guci tidak diekstraksi. Tetapi seperti yang telah ditunjukkan beberapa orang lainnya, Anda perlu membawa satu file tambahan agar berfungsi dengan baik. Ini adalah snip dari pom.xml
<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>
Sesuatu yang berhasil bagi saya adalah:
<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>
Saya memiliki kasus luar biasa karena ketergantungan saya pada sistem satu:
<dependency>
..
<scope>system</scope>
<systemPath>${project.basedir}/lib/myjar.jar</systemPath>
</dependency>
Saya telah mengubah kode yang disediakan oleh @ user189057 dengan perubahan: 1) maven-dependency-plugin dieksekusi di "prep-package" fase 2) Saya mengekstraksi classess yang tidak dibongkar secara langsung ke "target / class"
Saya mencoba jawaban paling banyak dipilih di sini, dan bisa mendapatkan jar runnable. Tetapi program tidak berjalan dengan benar. Saya tidak tahu alasannya. Ketika saya mencoba lari dariEclipse
, saya mendapatkan hasil yang berbeda tetapi ketika saya menjalankan jar dari baris perintah saya mendapatkan hasil yang berbeda (crash dengan kesalahan runtime khusus-program).
Saya memiliki persyaratan yang sama dengan OP hanya bahwa saya memiliki terlalu banyak (Maven) dependensi untuk proyek saya. Untungnya, satu-satunya solusi yang berhasil bagi saya adalah menggunakan itu Eclipse
. Sangat sederhana dan sangat mudah. Ini bukan solusi untuk OP tetapi merupakan solusi untuk seseorang yang memiliki persyaratan serupa tetapi dengan banyak ketergantungan Maven,
1) Cukup klik kanan pada folder proyek Anda (di Eclipse) dan pilih Export
2) Kemudian pilih Java
->Runnable Jar
3) Anda akan diminta untuk memilih lokasi file jar
4) Akhirnya, pilih kelas yang memiliki metode Utama yang ingin Anda jalankan dan pilih Package dependencies with the Jar file
dan klikFinish
Ini juga bisa menjadi pilihan, Anda dapat membuat file jar Anda
<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>
Bagi siapa pun yang mencari opsi untuk mengecualikan dependensi tertentu dari uber-jar, ini adalah solusi yang berfungsi untuk saya:
<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>
Jadi ini bukan konfigurasi mvn-assembly-plugin tetapi properti dari ketergantungan.
Sudah ada jutaan jawaban, saya ingin menambahkan Anda tidak perlu <mainClass>
jika Anda tidak perlu menambahkan entryPoint ke aplikasi Anda. Misalnya API mungkin belum tentu memiliki main
metode.
<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/
Tambahkan ke pom.xml:
<dependency>
<groupId>com.jolira</groupId>
<artifactId>onejar-maven-plugin</artifactId>
<version>1.4.4</version>
</dependency>
dan
<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>
Itu dia. Paket mvn berikutnya juga akan membuat satu guci lemak, termasuk semua guci ketergantungan.
Maven-assembly-plugin bekerja sangat baik untuk saya. Saya menghabiskan berjam-jam dengan maven-dependency-plugin dan tidak bisa membuatnya bekerja. Alasan utamanya adalah bahwa saya harus mendefinisikan di bagian konfigurasi secara eksplisit item artefak yang harus dimasukkan seperti yang dijelaskan dalam dokumentasi . Ada contoh di sana untuk kasus-kasus ketika Anda ingin menggunakannya seperti:, di mvn dependency:copy
mana tidak ada artifactItems tetapi tidak berfungsi.
Posting blog ini menunjukkan pendekatan lain dengan menggabungkan plugins maven-jar dan maven-assembly. Dengan konfigurasi perakitan xml dari posting blog, itu juga dapat dikontrol jika dependensi akan diperluas atau hanya dikumpulkan dalam folder dan direferensikan oleh entri classpath di manifes:
Solusi yang ideal adalah memasukkan toples ke folder lib dan file manifest.mf dari toples termasuk semua toples di classpath.
Dan persis yang dijelaskan di sini: 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>
Oke, jadi ini solusi saya. Saya tahu ini tidak menggunakan file pom.xml. Tapi saya punya masalah programmme saya mengkompilasi dan berjalan di Netbeans tetapi gagal ketika saya mencoba Java -jar MyJarFile.jar. Sekarang, saya tidak sepenuhnya mengerti Maven dan saya pikir ini mengapa mengalami kesulitan untuk mendapatkan Netbeans 8.0.2 untuk memasukkan file jar saya di perpustakaan untuk memasukkannya ke file jar. Saya berpikir tentang bagaimana saya menggunakan file jar tanpa Maven di Eclipse.
Itu Maven yang dapat mengkompilasi semua dependanice dan plugin. Bukan Netbeans. (Jika Anda bisa mendapatkan Netbeans dan dapat menggunakan java .jar untuk melakukan ini tolong beri tahu saya caranya (^. ^) V)
[Dipecahkan - untuk Linux] dengan membuka terminal.
Kemudian
cd /MyRootDirectoryForMyProject
Lanjut
mvn org.apache.maven.plugins:maven-compiler-plugin:compile
Lanjut
mvn install
Ini akan membuat file jar di direktori target.
MyJarFile-1.0-jar-with-dependencies.jar
Sekarang
cd target
(Anda mungkin perlu menjalankan chmod +x MyJarFile-1.0-jar-with-dependencies.jar
:)
Dan akhirnya
java -jar MyJarFile-1.0-jar-with-dependencies.jar
Tolong lihat
https://cwiki.apache.org/confluence/display/MAVEN/LifecyclePhaseNotFoundException
Saya akan memposting solusi ini pada beberapa halaman lain dengan masalah yang sama. Semoga saya bisa menyelamatkan seseorang dari rasa frustrasi selama seminggu.