Membangun toples lemak menggunakan maven


118

Saya memiliki basis kode yang ingin saya distribusikan sebagai jar. Ini juga memiliki ketergantungan pada toples eksternal, yang ingin saya bundel di toples terakhir.

Saya mendengar bahwa ini dapat dilakukan dengan menggunakan maven-assembly-plug-in, tetapi saya tidak mengerti caranya. Bisakah seseorang menunjukkan kepada saya beberapa contoh.

Saat ini, saya menggunakan toples lemak untuk menggabungkan toples terakhir. Saya ingin mencapai hal yang sama menggunakan maven.

Jawaban:


144

Catatan: Jika Anda adalah aplikasi boot-spring, baca akhir jawaban

Tambahkan plugin berikut ke Anda pom.xml Versi terbaru dapat ditemukan di

...
<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-assembly-plugin</artifactId>
            <version>CHOOSE LATEST VERSION HERE</version>
            <configuration>
                <descriptorRefs>
                    <descriptorRef>jar-with-dependencies</descriptorRef>
                </descriptorRefs>
            </configuration>
            <executions>
                <execution>
                    <id>assemble-all</id>
                    <phase>package</phase>
                    <goals>
                        <goal>single</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>
...

Setelah mengonfigurasi plugin ini, menjalankan mvn packageakan menghasilkan dua botol: satu hanya berisi kelas proyek, dan botol lemak kedua dengan semua dependensi dengan akhiran "-jar-with-dependencies".

jika Anda ingin classpathsetup yang benar saat runtime maka tambahkan juga plugin berikut

<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>

Untuk aplikasi boot musim semi gunakan hanya mengikuti plugin (pilih versi yang sesuai)

<plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    <configuration>
        <fork>true</fork>
        <mainClass>${start-class}</mainClass>
    </configuration>
    <executions>
        <execution>
            <goals>
                <goal>repackage</goal>
            </goals>
        </execution>
    </executions>
</plugin>

1
Versi saat ini dari plugin ini sekarang 2.4
guerda

13
Ini sekarang sudah tidak digunakan lagi dan maven-shade-plugin harus digunakan sebagai gantinya. Lihat jawaban @phlogratos: stackoverflow.com/a/16222965/274350 .
Richard Neish

2
Bisakah maven-assembly-plugin meminimalkan ukuran tabung lemak?
May12

1
@Richard Di mana Anda melihatnya sudah usang? Saya tidak dapat menemukan apa pun di sekitar sini maven.apache.org/plugins/maven-assembly-plugin
user3833308

3
@ user3833308 "deprecated" mungkin kata yang salah, tetapi dokumentasi di maven.apache.org/plugins/maven-assembly-plugin mengatakan "Jika proyek Anda ingin mengemas artefak Anda dalam uber-jar, plugin assembly hanya menyediakan dasar dukungan. Untuk kontrol lebih, gunakan Plugin Maven Shade. "
Richard Neish

55

Anda dapat menggunakan maven-shade-plugin .

Setelah mengonfigurasi plugin shade di build Anda, perintah mvn packageakan membuat satu jar dengan semua dependensi digabungkan ke dalamnya.


9
Ini sekarang cara yang benar untuk melakukannya. Dokumentasi maven-assembly-plugin menyatakan: "Jika proyek Anda ingin mengemas artefak Anda dalam uber-jar, plugin assembly hanya menyediakan dukungan dasar. Untuk kontrol lebih, gunakan Maven Shade Plugin."
Richard Neish

Tapi bagaimana cara mengambil single .jar dan menggunakannya untuk penerbitan?
DanGordon

42

Mungkin Anda ingin maven-shade-plugin, menggabungkan dependensi, meminimalkan kode yang tidak digunakan, dan menyembunyikan dependensi eksternal untuk menghindari konflik.

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-shade-plugin</artifactId>
            <version>3.1.1</version>
            <executions>
                <execution>
                    <phase>package</phase>
                    <goals>
                        <goal>shade</goal>
                    </goals>
                    <configuration>
                        <minimizeJar>true</minimizeJar>
                        <createDependencyReducedPom>true</createDependencyReducedPom>
                        <dependencyReducedPomLocation>
                            ${java.io.tmpdir}/dependency-reduced-pom.xml
                        </dependencyReducedPomLocation>
                        <relocations>
                            <relocation>
                                <pattern>com.acme.coyote</pattern>
                                <shadedPattern>hidden.coyote</shadedPattern>
                            </relocation>
                        </relocations>
                    </configuration>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

Referensi:


Jika ada yang bertemu Provider org.apache.xerces.jaxp.SAXParserFactoryImpl not found, hapus saja <minimizeJar>true</minimizeJar>.
koppor

Jika Anda mendapatkan pengecualian "java.lang.SecurityException: Intisari file tanda tangan tidak valid untuk atribut utama Manifes", maka penambahan ke bagian konfigurasi di atas ini membantu: stackoverflow.com/a/6743609/38368
Danny Varod

12

sebenarnya, menambahkan

<archive>
   <manifest>
    <addClasspath>true</addClasspath>
    <packageName>com.some.pkg</packageName>                     
    <mainClass>com.MainClass</mainClass>
  </manifest>
</archive>

deklarasi ke maven-jar-plugin tidak menambahkan entri kelas utama ke file manifes untuk saya. Saya harus menambahkannya ke maven-assembly-plugin untuk mendapatkannya di manifes


5

Anda dapat menggunakan plugin onejar-maven untuk pengemasan. Pada dasarnya, ini merakit proyek Anda dan dependensinya dalam satu jar, termasuk tidak hanya file jar proyek Anda, tetapi juga semua dependensi eksternal sebagai "jar of jars", mis.

<build>
    <plugins>
        <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>
    </plugins>
</build>

Catatan 1: Opsi konfigurasi tersedia di halaman beranda proyek .

Catatan 2: Karena satu dan lain hal, proyek onejar-maven-plugin tidak dipublikasikan di Maven Central. Namun jolira.com melacak proyek asli dan menerbitkannya dengan groupId com.jolira.


Apakah mungkin untuk memilih dependensi yang ingin Anda paketkan? Misalnya, jika a.jar dan b.jar adalah stoples eksternal dan saya hanya ingin mengemas a.jar ke dalam stoples terakhir, apakah itu mungkin / dapat dikonfigurasi?
bianca

Saya juga melihat barang-barang satu botol dibundel dalam toples terakhir juga. Ini meningkatkan ukuran toples akhir banyak. Apakah mungkin untuk memilih toples eksternal yang ingin Anda masukkan ke dalam toples terakhir? Ini adalah log satu botol: pastebin.com/UwniQJ2X
bianca

Saya tidak tahu apakah Anda dapat mengonfigurasi apa yang disertakan atau tidak. Pada dasarnya, one-jar menyertakan semua dependensi yang ditentukan oleh project Anda, termasuk dependensi transitif, jadi ya, toples terakhir kemungkinan besar akan menjadi besar jika Anda memiliki banyak dependensi. Beberapa biaya tambahan akan ditambahkan oleh satu botol, agar Java dapat bekerja dengan struktur "toples".
matsev

2

Alternatifnya adalah dengan menggunakan plugin maven shade untuk membuat file uber-jar.

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-shade-plugin</artifactId>
    <version> Your Version Here </version>
    <configuration>
            <!-- put your configurations here -->
    </configuration>
    <executions>
            <execution>
                    <phase>package</phase>
                    <goals>
                            <goal>shade</goal>
                    </goals>
            </execution>
    </executions>
</plugin>
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.