Побудова жирової банки за допомогою Maven


118

У мене є база коду, яку я хочу розповсюдити як jar. Він також має залежність від зовнішніх баночок, які я хочу зв'язати в останню банку.

Я чув, що це можна зробити, використовуючи maven-assembly-plug-in, але не розумію, як. Невже хтось може вказати мені на деякі приклади.

Зараз я використовую жирову банку, щоб зв’язати останню банку. Я хочу досягти того ж, використовуючи maven.

Відповіді:


143

Примітка. Якщо ви користуєтеся додатком для завантаження, прочитайте кінець відповіді

Додайте наступний плагін до pom.xml останньої версії, яку можна знайти за адресою

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

Після налаштування цього плагіна запуск mvn packageбуде виробляти дві банки: одна, що містить лише проектні класи, а друга - жирова банка з усіма залежностями з суфіксом "-jar-with-зависимост".

якщо ви хочете правильної classpathустановки під час виконання, тоді також додайте наступний плагін

<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>
    <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
Поточна версія цього плагіна тепер
guerda

13
Це тепер застаріле і замість нього слід використовувати плагін maven-shadow. Див @phlogratos відповідь: stackoverflow.com/a/16222965/274350 .
Річард Ніш

2
Чи може maven-Assembly-plugin мінімізувати розмір жирової банки?
травня 12

1
@Richard Де ви вважаєте, що це застаріле? Я нічого не міг знайти тут maven.apache.org/plugins/maven-assembly-plugin
user3833308

3
@ user3833308 "застаріле" може бути неправильним словом, але в документації на maven.apache.org/plugins/maven-assembly-plugin написано: "Якщо ваш проект хоче запакувати ваш артефакт в uber-jar, плагін для складання забезпечує лише основні підтримка. Для більшого контролю використовуйте плагін Maven Shade. "
Річард Ніш

55

Ви можете використовувати плагін Maven-shadow-плагін .

Після налаштування плагіна відтінку у вашій збірці команда mvn packageстворить одну єдину банку з усіма залежностями, об'єднаними в неї.


9
Зараз це правильний спосіб зробити це. Документація щодо модуля maven-Assembly-plugin зазначає: "Якщо ваш проект хоче запакувати ваш артефакт в uber-jar, плагін для складання забезпечує лише основну підтримку. Для більшого контролю використовуйте плагін Maven Shade."
Річард Ніш

Але як мені взяти цей сингл .jar і використовувати його для публікації?
DanGordon

42

Можливо, ви хочете maven-shade-plugin, згрупуйте залежності, мінімізуйте невикористаний код і прихойте зовнішні залежності, щоб уникнути конфліктів.

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

Список літератури:


Якщо хтось стикається Provider org.apache.xerces.jaxp.SAXParserFactoryImpl not found, просто видаліть <minimizeJar>true</minimizeJar>.
коппор

Якщо ви отримуєте «java.lang.SecurityException: Invalid файл підпису дайджесту для маніфесту головних атрибутів» виняток, то це додаток до вище в розділі конфігурації допомагає: stackoverflow.com/a/6743609/38368
Денні Varod

12

власне, додаючи

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

декларація maven-jar-plugin не додає основний запис до файлу маніфесту для мене. Мені довелося додати його до плагіна maven-Assembly-плагін, щоб отримати це в маніфесті


5

Для упаковки можна використовувати плагін onejar-maven . В основному, він збирає ваш проект та його залежності в одну банку, включаючи не лише ваш файл jar-файлу проекту, але й усі зовнішні залежності як "банку з банки", наприклад

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

Примітка 1: Параметри конфігурації доступні на домашній сторінці проекту .

Примітка 2: З тієї чи іншої причини проект onejar-maven-plugin не публікується в Maven Central. Однак jolira.com відстежує оригінальний проект і публікує його разом з groupId com.jolira.


Чи можна вибрати залежності, які ви хочете упакувати? Наприклад, якщо a.jar і b.jar є зовнішніми банками, і я хочу пакувати лише a.jar в остаточну банку, чи можливо це щось / що можна налаштувати?
bianca

Я також бачу, що речі з однієї банки також вкладаються в остаточну банку. Це значно збільшило розмір кінцевої банки. Чи можна вибрати зовнішні банки, які ви маєте намір включити в остаточну банку? Ось журнали з однією банку: pastebin.com/UwniQJ2X
bianca

Я не знаю, ви можете налаштувати те, що включено чи ні. В основному, одна jar включає всі залежності, які визначені вашим проектом, включаючи перехідні залежності, так що так, остаточний jar, ймовірно, стане великим, якщо у вас багато залежностей. Деякі накладні витрати будуть додані однією jar, щоб Java працювала зі структурою "jar of банки".
мацев

2

В якості альтернативи можна використовувати Maven тіні плагін , щоб побудувати 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>
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.