Costruire un barattolo di grasso usando Maven


118

Ho una base di codice che voglio distribuire come jar. Ha anche una dipendenza da vasi esterni, che voglio raggruppare nel vaso finale.

Ho sentito che questo può essere fatto usando maven-assembly-plug-in, ma non capisco come. Qualcuno potrebbe indicarmi alcuni esempi.

In questo momento, sto usando il vaso grasso per raggruppare il vaso finale. Voglio ottenere la stessa cosa usando Maven.

Risposte:


143

Nota: se sei un'applicazione con avvio a molla, leggi la fine della risposta

Aggiungi il seguente plugin al tuo pom.xml L'ultima versione può essere trovata su

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

Dopo aver configurato questo plug-in, l'esecuzione mvn packageprodurrà due jar: uno contenente solo le classi del progetto e un secondo fat jar con tutte le dipendenze con il suffisso "-jar-with-dependencies".

se si desidera una corretta classpathconfigurazione in fase di esecuzione, aggiungere anche il seguente plug-in

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

Per l'applicazione di avvio primaverile utilizzare solo il plug-in seguente (scegliere la versione appropriata di esso)

<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
La versione attuale di questo plugin è ora 2.4
guerda

13
Questo è ora deprecato e al suo posto dovrebbe essere usato il plugin maven-shade. Vedi @phlogratos rispondono: stackoverflow.com/a/16222965/274350 .
Richard Neish

2
Può maven-assembly-plugin minimizzare le dimensioni del fat jar?
maggio

1
@Richard Dove vedi che è deprecato? Non sono riuscito a trovare nulla qui intorno maven.apache.org/plugins/maven-assembly-plugin
user3833308

3
@ user3833308 "deprecato" potrebbe essere la parola sbagliata, ma la documentazione su maven.apache.org/plugins/maven-assembly-plugin dice "Se il tuo progetto vuole impacchettare il tuo artefatto in un uber-jar, il plugin assembly fornisce solo supporto. Per un maggiore controllo, utilizza il plug-in Maven Shade ".
Richard Neish

55

Puoi usare il plug-in Maven-Shade .

Dopo aver configurato il plug-in ombra nella tua build, il comando mvn packagecreerà un singolo jar con tutte le dipendenze unite al suo interno.


9
Questo è ora il modo corretto per farlo. La documentazione di maven-assembly-plugin afferma: "Se il tuo progetto vuole impacchettare il tuo artefatto in un uber-jar, il plug-in assembly fornisce solo il supporto di base. Per un maggiore controllo, usa il plug-in Maven Shade."
Richard Neish

Ma come prendo quel singolo .jar e lo uso per la pubblicazione?
DanGordon

42

Forse vuoi maven-shade-pluginraggruppare le dipendenze, ridurre al minimo il codice inutilizzato e nascondere le dipendenze esterne per evitare conflitti.

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

Riferimenti:


Se si incontra Provider org.apache.xerces.jaxp.SAXParserFactoryImpl not found, basta rimuovere <minimizeJar>true</minimizeJar>.
koppor

Se si ottiene un "java.lang.SecurityException: file di firma non valido digerire per Manifest attributi principali" eccezione, allora questa aggiunta alla sezione di configurazione sopra aiuta: stackoverflow.com/a/6743609/38368
Danny Varod

12

in realtà, aggiungendo il file

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

la dichiarazione a maven-jar-plugin non aggiunge la voce della classe principale al file manifest per me. Ho dovuto aggiungerlo al plugin maven-assembly per ottenerlo nel manifest


5

Puoi usare il plug-in onejar-maven per il packaging. Fondamentalmente, assembla il tuo progetto e le sue dipendenze in un unico jar, includendo non solo il file jar del tuo progetto, ma anche tutte le dipendenze esterne come un "jar of jars", ad es.

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

Nota 1: le opzioni di configurazione sono disponibili nella home page del progetto .

Nota 2: per un motivo o per l'altro, il progetto onejar-maven-plugin non è pubblicato su Maven Central. Tuttavia jolira.com tiene traccia del progetto originale e lo pubblica con il groupId com.jolira.


È possibile scegliere le dipendenze con cui si desidera creare un pacchetto? Ad esempio, se a.jar e b.jar sono jar esterni e desidero impacchettare solo a.jar nel jar finale, è qualcosa di possibile / configurabile?
bianca

Vedo anche che le cose di un barattolo sono state impacchettate anche nel vaso finale. Questa ha aumentato molto le dimensioni del barattolo finale. È possibile scegliere barattoli esterni che intendi includere nel barattolo finale? Ecco i registri one-jar: pastebin.com/UwniQJ2X
bianca

Non so se puoi configurare cosa è incluso o meno. Fondamentalmente, one-jar include tutte le dipendenze specificate dal tuo progetto, comprese le dipendenze transitive, quindi sì, è probabile che il jar finale diventi grande se hai molte dipendenze. Un po 'di overhead verrà aggiunto da one-jar, in modo che Java funzioni con la struttura "jar of jars".
matsev

2

Un'alternativa è quella di utilizzare l'esperto ombra plugin per costruire un 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>
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.