2865 votes

Comment puis-je créer un fichier exécutable jar avec des dépendances à l'aide de Maven?

J'ai écrit un petit utilitaire à courir à partir de la ligne de commande à l'aide de Java. Je veux de l'empaqueter dans un seul exécutable jar pour la distribution (.fichier jar).

Comment puis-je faire maven paquet tous les dependend bocaux dans mon pot?

2788voto

IAdapter Points 15876
<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>

et vous l'exécutez avec

mvn clean compile assembly:single

Compiler objectif doit être ajouté avant l'assemblée:seul ou sinon le code sur votre propre projet n'est pas inclus.

Voir plus de détails dans les commentaires.


Souvent cet objectif est lié à une phase de construction d'exécuter automatiquement. Cela garantit que le BOCAL est construit lors de l'exécution d' mvn install ou l'exécution d'un déploiement/release.

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

406voto

André Aronsen Points 981

Vous pouvez utiliser la dépendance-plugin pour générer toutes les dépendances dans un répertoire séparé avant que le paquet de phase, puis de l'inclure dans le classpath du manifeste:

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

Vous pouvez également utiliser "${projet.construire.annuaire}/classes/lib" comme OutputDirectory à intégrer tous les jar-les fichiers dans le pot, mais alors vous aurez besoin d'ajouter des classloading le code pour charger les pots.

324voto

Jin Kwon Points 2191

J'ai blogué trois façons différentes de le faire. Voir Exécutable Jar avec Apache Maven

maven-jar-plugin avec maven-dépendance-plugin

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-dependency-plugin</artifactId>
  <version>2.8</version>
  <executions>
    <execution>
      <id>copy-dependencies</id>
      <phase>package</phase>
      <goals>
        <goal>copy-dependencies</goal>
      </goals>
      <configuration>
        <outputDirectory>${project.build.directory}/${project.build.finalName}.lib</outputDirectory>
      </configuration>
    </execution>
  </executions>
</plugin>

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-jar-plugin</artifactId>
  <version>2.4</version>
  <configuration>
    <archive>
      <manifest>
        <addClasspath>true</addClasspath>
        <classpathPrefix>${project.build.finalName}.lib/</classpathPrefix>
        <mainClass>com.github.jinahya.Main</mainClass>
      </manifest>
    </archive>
  </configuration>
</plugin>

maven-assembly-plugin

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-assembly-plugin</artifactId>
  <version>2.4</version>
  <configuration>
    <archive>
      <manifest>
        <mainClass>com.github.jinahya.Main</mainClass>
      </manifest>
    </archive>
    <descriptorRefs>
      <descriptorRef>jar-with-dependencies</descriptorRef>
    </descriptorRefs>
  </configuration>
</plugin>

maven-ombre-plugin

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-shade-plugin</artifactId>
  <version>2.3</version>
  <configuration>
    <shadedArtifactAttached>true</shadedArtifactAttached>
    <transformers>
      <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
        <mainClass>com.github.jinahya.Main</mainClass>
      </transformer>
    </transformers>
  </configuration>
  <executions>
    <execution>
      <id>shade</id>
      <!--phase>package</phase--> <!-- default -->
      <goals>
        <goal>shade</goal>
      </goals>
    </execution>
  </executions>
</plugin>

onejar-maven-plugin

<plugin>
  <!--groupId>org.dstovall</groupId--> <!-- not available on the central -->
  <groupId>com.jolira</groupId>
  <artifactId>onejar-maven-plugin</artifactId>
  <version>1.4.4</version>
  <executions>
    <execution>
      <configuration>
        <mainClass>com.github.jinahya.Main</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>

157voto

Matthew McCullough Points 7713

Prenant sans Réponse de la réponse et de le reformater, nous avons:

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

Ensuite, je tiens à recommander ce qui en fait une partie naturelle de votre construction, plutôt que d'en appeler explicitement. Pour en faire une partie intégrante de votre construction, ajouter ce plugin pour votre pom.xml et le lier à l' package événement de cycle de vie. Cependant, une chasse aux sorcières, c'est que vous devez appeler l' assembly:single objectif de mettre ceci dans votre pom.xml tandis que vous appelez de l'assemblée:l'assemblée " si l'exécution manuellement à partir de la ligne de commande.

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

102voto

Vijay Katam Points 411

Utiliser le maven-ombre-plugin pour le package de toutes les dépendances dans un uber-jar. Il peut également être utilisé pour générer un fichier exécutable jar en spécifiant la classe principale. Après avoir essayé d'utiliser maven-assembly et maven-jar , j'ai trouvé que ce plugin mieux adapté à mes besoins.

J'ai trouvé ce plugin particulièrement utile car il fusionne le contenu de certains fichiers au lieu de les écraser. Ceci est nécessaire quand il y a des fichiers de ressources qui ont le même nom dans les pots et le plugin tente de paquet de tous les fichiers de ressources

Voir l'exemple ci-dessous

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X