Bauen eines fetten Glases mit Maven


118

Ich habe eine Codebasis, die ich als jar verteilen möchte. Es hängt auch von externen Gläsern ab, die ich im letzten Glas bündeln möchte.

Ich habe gehört, dass dies mit gemacht werden kann maven-assembly-plug-in, aber ich verstehe nicht wie. Könnte mich jemand auf einige Beispiele hinweisen.

Im Moment benutze ich ein fettes Glas, um das letzte Glas zu bündeln. Ich möchte dasselbe mit Maven erreichen.

Antworten:


143

Hinweis: Wenn Sie eine Spring-Boot-Anwendung sind, lesen Sie das Ende der Antwort

Fügen Sie Ihrem Plugin folgendes Plugin hinzu. pom.xml Die neueste Version finden Sie unter

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

Nach der Konfiguration dieses Plug- mvn packageIns werden beim Ausführen zwei Jars erstellt: eines enthält nur die Projektklassen und ein zweites Fat Jar mit allen Abhängigkeiten mit dem Suffix "-jar-with-dependencies".

Wenn Sie classpathzur Laufzeit ein korrektes Setup wünschen, fügen Sie auch das folgende Plugin hinzu

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

Verwenden Sie für Spring Boot-Anwendungen nur das folgende Plugin (wählen Sie die entsprechende Version aus).

<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
Aktuelle Version dieses Plugins ist jetzt 2.4
Guerda

13
Dies ist jetzt veraltet und das Maven-Shade-Plugin sollte stattdessen verwendet werden. Siehe @ phlogratos Antwort: stackoverflow.com/a/16222965/274350 .
Richard Neish

2
Kann das Maven-Assembly-Plugin die Größe des Fettgefäßes minimieren?
12. Mai

1
@ Richard Wo sehen Sie, dass es veraltet ist? Ich konnte hier nichts finden maven.apache.org/plugins/maven-assembly-plugin
user3833308

3
@ user3833308 "veraltet" ist möglicherweise das falsche Wort, aber in der Dokumentation unter maven.apache.org/plugins/maven-assembly-plugin heißt es: "Wenn Ihr Projekt Ihr Artefakt in einem Uber-Jar verpacken möchte, bietet das Assembly-Plugin nur grundlegende Informationen Unterstützung. Verwenden Sie für mehr Kontrolle das Maven Shade Plugin. "
Richard Neish

55

Sie können das Maven-Shade-Plugin verwenden .

Nach dem Konfigurieren des Shadow-Plugins in Ihrem Build erstellt der Befehl mvn packageein einzelnes JAR mit allen darin zusammengeführten Abhängigkeiten.


9
Dies ist jetzt der richtige Weg. In der Dokumentation zum Maven-Assembly-Plugin heißt es: "Wenn Ihr Projekt Ihr Artefakt in einem Uber-Jar verpacken möchte, bietet das Assembly-Plugin nur grundlegende Unterstützung. Verwenden Sie für mehr Kontrolle das Maven Shade Plugin."
Richard Neish

Aber wie nehme ich diese einzelne .jar und verwende sie zum Veröffentlichen?
DanGordon

42

Vielleicht möchten Sie maven-shade-pluginAbhängigkeiten bündeln, nicht verwendeten Code minimieren und externe Abhängigkeiten ausblenden, um Konflikte zu vermeiden.

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

Verweise:


Wenn man auf Provider org.apache.xerces.jaxp.SAXParserFactoryImpl not foundetwas stößt , einfach entfernen <minimizeJar>true</minimizeJar>.
Koppor

Wenn Sie die Ausnahme "java.lang.SecurityException: Ungültiger Signaturdatei-Digest für Manifest-Hauptattribute" erhalten, hilft dieser Zusatz zum obigen Konfigurationsabschnitt: stackoverflow.com/a/6743609/38368
Danny Varod

12

eigentlich das Hinzufügen der

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

Durch die Deklaration an das maven-jar-plugin wird der Hauptklasseneintrag für mich nicht zur Manifestdatei hinzugefügt. Ich musste es dem Maven-Assembly-Plugin hinzufügen, um es in das Manifest zu bekommen


5

Sie können das onejar-maven-Plugin zum Verpacken verwenden. Grundsätzlich werden Ihr Projekt und seine Abhängigkeiten in einem JAR zusammengefasst, einschließlich nicht nur Ihrer Projekt-JAR-Datei, sondern auch aller externen Abhängigkeiten als "JAR-JAR", z

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

Anmerkung 1: Konfigurationsoptionen bei der Projekt zur Verfügung Homepage .

Hinweis 2: Aus dem einen oder anderen Grund wird das onejar-maven-plugin-Projekt nicht in Maven Central veröffentlicht. Allerdings jolira.com verfolgt das ursprüngliche Projekt und veröffentlicht es mit dem groupId com.jolira.


Ist es möglich, Abhängigkeiten auszuwählen, mit denen Sie verpacken möchten? Wenn beispielsweise a.jar und b.jar externe Gläser sind und ich nur a.jar in das endgültige Glas verpacken möchte, ist dies möglich / konfigurierbar?
Bianca

Ich sehe auch, dass Ein-Glas-Sachen auch im letzten Glas gebündelt wurden. Dies vergrößerte das endgültige Glas sehr. Ist es möglich, externe Gläser auszuwählen, die Sie in das endgültige Glas aufnehmen möchten? Hier ist die Ein-Glas-Protokolle: pastebin.com/UwniQJ2X
bianca

Ich weiß nicht, ob Sie konfigurieren können, was enthalten ist oder nicht. Grundsätzlich enthält ein JAR alle Abhängigkeiten, die von Ihrem Projekt angegeben werden, einschließlich der transitiven Abhängigkeiten. Ja, das endgültige JAR wird wahrscheinlich groß, wenn Sie viele Abhängigkeiten haben. Ein JAR wird etwas Overhead hinzufügen, damit Java mit der Struktur "jar of jars" funktioniert.
Matsev

2

Eine Alternative ist die Verwendung des Maven Shade Plugins zum Erstellen eines 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>
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.