Domanda Come posso creare un JAR eseguibile con dipendenze usando Maven?


Voglio impacchettare il mio progetto in un unico JAR eseguibile per la distribuzione.

Come posso creare un pacchetto di progetti Maven con tutti i JAR di dipendenza nel mio JAR di output?


1939
2018-02-22 08:43


origine


risposte:


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

e tu lo gestisci con

mvn clean compile assembly:single

L'obiettivo di compilazione deve essere aggiunto prima dell'assemblaggio: singolo o altrimenti il ​​codice sul proprio progetto non è incluso.

Vedi più dettagli nei commenti.


Comunemente questo obiettivo è legato ad una fase di build da eseguire automaticamente. Ciò assicura che il JAR sia costruito durante l'esecuzione mvn install o eseguire una distribuzione / rilascio.

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

1864
2017-12-01 10:46



Puoi usare il plugin dependance per generare tutte le dipendenze in una directory separata prima della fase del pacchetto e quindi includerlo nel classpath del manifest:

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

In alternativa, usa ${project.build.directory}/classes/lib come OutputDirectory per integrare tutti i file jar nel jar principale, ma in seguito sarà necessario aggiungere codice di caricamento classi personalizzato per caricare i jar.


294
2018-06-02 03:01



Ho bloggato su alcuni modi diversi per farlo.

Vedere Jar eseguibile con Apache Maven (WordPress)

o eseguibile-jar-con-maven-example (GitHub)

Gli appunti

Questi pro e contro sono forniti da Stephan.


Per la distribuzione manuale

  • Professionisti
  • Contro
    • Le dipendenze sono fuori dal vaso finale.

Copia le dipendenze in una directory specifica

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

Rendere eseguibile il jar e classpath consapevole

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

A questo punto il jar è in realtà eseguibile con elementi di classpath esterni.

$ java -jar target/${project.build.finalName}.jar

Crea archivi deployabili

Il jar il file è eseguibile solo con il fratello ...lib/ directory. Dobbiamo creare archivi da implementare con la directory e il suo contenuto.

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

Ora hai target/${project.build.finalName}.(zip|tar|tar.bz2|tar.gz) che contiene ciascuno il jar e lib/*.


Apache Maven Assembly Plugin

  • Professionisti
  • Contro
    • Nessun supporto per il trasferimento di classe (usa maven-shade-plugin se è necessario il riposizionamento di classe).
<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>

Hai target/${project.bulid.finalName}-jar-with-dependencies.jar.


Apache Maven Shade Plugin

  • Professionisti
  • Contro
<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>

Hai target/${project.build.finalName}-shaded.jar.


onejar-maven-plugin

  • Professionisti
  • Contro
    • Non supportato attivamente dal 2012.
<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>

Spring Boot Maven Plugin

  • Professionisti
  • Contro
    • Aggiungi potenziali classi correlate Spring e Spring Boot.
<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>

Hai target/${project.bulid.finalName}-spring-boot.jar.


134
2018-02-26 04:31



Prendendo la risposta di Unanswered e riformattandola, abbiamo:

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

Quindi, ti consiglio di renderlo una parte naturale della tua build, piuttosto che qualcosa da chiamare esplicitamente. Per renderlo parte integrante della tua build, aggiungi questo plugin al tuo pom.xml e legalo al package evento del ciclo di vita. Tuttavia, un trucco è che è necessario chiamare il assembly:single obiettivo se inserisci questo nel tuo pom.xml, mentre chiameresti 'assembly: assembly' se lo esegui manualmente dalla riga di comando.

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

122
2017-09-22 15:20



Usa il plugin maven-shade per raggruppare tutte le dipendenze in un uber-jar. Può anche essere usato per costruire un jar eseguibile specificando la classe principale. Dopo aver provato ad usare maven-assembly e maven-jar, ho trovato che questo plugin si adattava meglio alle mie esigenze.

Ho trovato questo plugin particolarmente utile in quanto unisce il contenuto di file specifici anziché sovrascriverli. Questo è necessario quando ci sono file di risorse che hanno lo stesso nome attraverso i jar e il plugin tenta di comprimere tutti i file di risorse

Vedi l'esempio qui sotto

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

91
2018-03-13 20:55



A lungo usato il plugin di montaggio di Maven, ma non sono riuscito a trovare una soluzione al problema "already added, skipping". Ora, sto usando un altro plugin - onejar-maven-plugin. Esempio di seguito (mvn package costruire un barattolo):

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

Devi aggiungere repository per quel plugin:

<pluginRepositories>
    <pluginRepository>
        <id>onejar-maven-plugin.googlecode.com</id>
        <url>http://onejar-maven-plugin.googlecode.com/svn/mavenrepo</url>
    </pluginRepository>
</pluginRepositories>

15
2017-10-13 12:16



Puoi usare maven-dependency-plugin, ma la domanda era come creare un JAR eseguibile. Per farlo è necessaria la seguente modifica alla risposta di Matthew Franglen (btw, usare il plugin di dipendenza richiede più tempo per essere compilato quando si parte da una destinazione pulita):

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

14
2018-03-11 15:12



Un'altra opzione se si desidera veramente riconfezionare gli altri contenuti dei JAR all'interno del proprio JAR risultante è il Plugin di Maven Assembly. Spacchetta e poi reimposta tutto in una directory tramite <unpack>true</unpack>. Poi avresti un secondo passaggio che lo ha costruito in un massiccio JAR.

Un'altra opzione è il plugin OneJar. Questo esegue le azioni di riconfezionamento di cui sopra in un unico passaggio.


13
2017-08-13 18:23



Puoi aggiungere quanto segue al tuo pom.xml:

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

Successivamente devi passare dalla console alla directory, dove si trova pom.xml. Quindi devi eseguire assemblaggio MVV: singolo e si spera che il tuo file JAR eseguibile con dipendenze si sviluppi. È possibile controllarlo quando si passa alla directory di output (destinazione) con cd ./target e iniziando il tuo vaso con un comando simile a java -jar mavenproject1-1.0-SNAPSHOT-jar-with-dependencies.jar.

Ho provato questo con Apache Maven 3.0.3.


11
2017-11-26 14:17



Potresti combinare il maven-shade-plugin e maven-jar-plugin.

  • Il maven-shade-plugin racchiude le tue classi e tutte le dipendenze in un singolo file jar.
  • Configura il maven-jar-plugin per specificare la classe principale del tuo jar eseguibile (vedi Impostare il percorso di classe, capitolo "Rendere il vaso eseguibile").

Esempio di configurazione POM per 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>

Infine crea il jar eseguibile richiamando:

mvn clean package shade:shade

8
2017-11-23 20:28



Ho esaminato ognuna di queste risposte cercando di creare un grosso contenitore eseguibile contenente tutte le dipendenze e nessuno di questi ha funzionato correttamente. La risposta è il plugin per l'ombra, è molto semplice e diretto.

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

Essere consapevoli del fatto che le proprie dipendenze devono avere un ambito di compilazione o runtime affinché funzioni correttamente.

Questo esempio è venuto da mkyong.com


8
2017-09-09 13:37