Y compris les dépendances dans un bocal avec Maven

Est-il un moyen de forcer maven(2.0.9) pour inclure toutes les dépendances dans un seul fichier jar?

j'ai un projet construit dans un seul fichier jar. Je veux que les classes des dépendances soient aussi copiées dans le pot.

mise à Jour: je sais que je ne peux pas simplement inclure un fichier jar dans un fichier jar. Je cherche un moyen de déballer les bocaux qui sont spécifiés comme dépendances, et d'empaqueter les fichiers de classe dans mon bocal.

264
demandé sur James McMahon 2009-11-13 15:51:24

13 réponses

vous pouvez le faire en utilisant le plugin Maven-assembly avec le descripteur" jar-with-dependencies". Voici le morceau pertinent d'un de nos pom.xml qui fait ceci:

  <build>
    <plugins>
      <!-- any other plugins -->
      <plugin>
        <artifactId>maven-assembly-plugin</artifactId>
        <executions>
          <execution>
            <phase>package</phase>
            <goals>
              <goal>single</goal>
            </goals>
          </execution>
        </executions>
        <configuration>
          <descriptorRefs>
            <descriptorRef>jar-with-dependencies</descriptorRef>
          </descriptorRefs>
        </configuration>
      </plugin>
    </plugins>
  </build>
381
répondu John Stauffer 2015-04-23 09:54:33

avec Maven 2, la bonne façon de faire ceci est d'utiliser le Plugin D'assemblage Maven2 qui a un fichier de descripteur prédéfini à cet effet et que vous pouvez simplement utiliser sur la ligne de commande:

mvn assembly:assembly -DdescriptorId=jar-with-dependencies

si vous voulez rendre ce jar exécutable, il suffit d'ajouter la classe principale à exécuter à la configuration du plugin:

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-assembly-plugin</artifactId>
  <configuration>
    <archive>
      <manifest>
        <mainClass>my.package.to.my.MainClass</mainClass>
      </manifest>
    </archive>
  </configuration>
</plugin>

Si vous voulez créer cette assemblée dans le cadre de la normale processus de construction, vous devriez lier le simple ou répertoire-simple but (le assembly but ne doit être exécuté à partir de la ligne de commande) à une phase du cycle de vie ( package fait sens), quelque chose comme ceci:

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-assembly-plugin</artifactId>
  <executions>
    <execution>
      <id>create-my-bundle</id>
      <phase>package</phase>
      <goals>
        <goal>single</goal>
      </goals>
      <configuration>
        <descriptorRefs>
          <descriptorRef>jar-with-dependencies</descriptorRef>
        </descriptorRefs>
        ...
      </configuration>
    </execution>
  </executions>
</plugin>

adaptez l'élément configuration à vos besoins (par exemple avec le manifeste tel que parlé).

114
répondu Pascal Thivent 2012-07-18 09:30:04

Si vous voulez faire un fichier jar exécutable, leur besoin de définir la classe principale. Donc la configuration complète devrait l'être.

    <plugins>
            <plugin>
                 <artifactId>maven-assembly-plugin</artifactId>
                 <executions>
                     <execution>
                          <phase>package</phase>
                          <goals>
                              <goal>single</goal>
                          </goals>
                      </execution>
                  </executions>
                  <configuration>
                       <!-- ... -->
                       <archive>
                           <manifest>
                                 <mainClass>fully.qualified.MainClass</mainClass>
                           </manifest>
                       </archive>
                       <descriptorRefs>
                           <descriptorRef>jar-with-dependencies</descriptorRef>
                      </descriptorRefs>
                 </configuration>
         </plugin>
   </plugins>
18
répondu abdiel 2016-12-29 17:18:13

Il y a les l'ombre plugin maven . Il peut être utilisé pour "151930920 de package et de le renommer dépendances (omettre les problèmes de dépendance dans le classpath).

12
répondu Thomas Jung 2009-11-13 13:02:03

si vous (comme moi) n'aimez pas particulièrement l'approche jar-with-dependencies décrite ci-dessus, la solution maven que je préfère est simplement de construire un projet de guerre, même si ce n'est qu'une application java autonome que vous construisez:

  1. faites un projet maven jar normal, qui construira votre fichier jar (sans les dépendances).

  2. aussi, mettre en place un projet de guerre maven (avec seulement un src/main/webapp/WEB-INF/web vide.xml fichier, qui évitera un avertissement / erreur dans le maven-build), qui a seulement votre jar-projet comme une dépendance, et faire de votre jar-projet un <module> sous votre war-projet. (Ce projet de guerre n'est qu'un simple truc pour envelopper toutes les dépendances de vos fichiers jar dans un fichier zip.)

  3. Construire la guerre-projet visant à produire de la guerre-fichier.

  4. Dans l'étape de déploiement, renommez simplement votre .la guerre du fichier *.zip et décompressez-le.

vous devriez maintenant avoir un répertoire lib (que vous pouvez déplacer où vous le voulez) avec votre jar et toutes les dépendances dont vous avez besoin pour exécuter votre application:

java -cp 'path/lib/*' MainClass

(le Joker dans classpath works en Java-6 ou supérieur)

je pense que c'est à la fois plus simple à configurer dans maven (pas besoin de jouer avec le plugin d'assemblage) et vous donne également une vue plus claire de l'application-structure (vous verrez les numéros de version de tous les pots dépendants en vue, et éviter de tout colmater dans un seul jar-file).

11
répondu Rop 2015-05-08 20:10:35

vous pouvez utiliser le pot nouvellement créé en utilisant une étiquette <classifier> .

<dependencies>
    <dependency>
        <groupId>your.group.id</groupId>
        <artifactId>your.artifact.id</artifactId>
        <version>1.0</version>
        <type>jar</type>
        <classifier>jar-with-dependencies</classifier>
    </dependency>
</dependencies>
11
répondu lasantha 2017-07-25 15:37:37

http://fiji.sc/Uber-JAR fournit une excellente explication des alternatives:

il y a trois méthodes communes pour construire un Uber-JAR:

  1. sans abat-jour. Déballez tous les fichiers JAR, puis remettez-les dans un seul JAR.
    • Pro: fonctionne avec le chargeur de classe par défaut de Java.
    • Con: fichiers présents dans plusieurs fichiers JAR avec le même chemin d'accès (par ex., META-INF/services / javax.script.ScriptEngineFactory) va en écraser un l'autre, provoquant un comportement incorrect.
    • Outils: Maven Assembly Plugin, Classworlds Uberjar
  2. ombré. Identique à unshaded, mais renommer (i.e., "shade") tous les paquets de toutes les dépendances.
    • Pro: fonctionne avec le chargeur de classe par défaut de Java. Évite certains (pas tous) conflits de versions de dépendances.
    • Con: Files présent dans plusieurs fichiers JAR avec le même chemin (par ex., META-INF/services / javax.script.ScriptEngineFactory) va en écraser un l'autre, provoquant un comportement incorrect.
    • Outils: Maven Shade Plugin
  3. pot de bocaux. Le fichier JAR final contient les autres fichiers JAR inclus.
    • Pro: évite les conflits de versions de dépendances. Tout les fichiers de ressources sont préservées.
    • Con: doit regrouper un spécial "bootstrap" classloader pour permettre à Java de charger des classes à partir du des dossiers de pots emballés. Les problèmes de débogage du chargeur de classe deviennent plus complexes.
    • Outils: Eclipse Fichier JAR Exportateur, d'Un JAR.
9
répondu André Valenti 2016-10-07 23:41:44

ma solution définitive sur Eclipse Luna et m2eclipse: Personnaliser Classloader (télécharger et ajouter à votre projet, 5 classes seulement) : http://git.eclipse.org/c/jdt/eclipse.jdt.ui.git/plain/org.eclipse.jdt.ui/jar%20in%20jar%20loader/org/eclipse/jdt/internal/jarinjarloader / ; ce classloader est le meilleur de la classloader à un bocal et très rapide;

<project.mainClass>org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader</project.mainClass> <project.realMainClass>my.Class</project.realMainClass>

Modifier dans JIJConstants "Rsrc-Class-Path" à la "Classe-Chemin"

mvn clean dependency: paquet de copy-dependencies

est créé un jar avec des dépendances dans le dossier lib avec un classloader fin

<build>
    <resources>
        <resource>
            <directory>src/main/java</directory>
            <includes>
                <include>**/*.java</include>
                <include>**/*.properties</include>
            </includes>
        </resource>
        <resource>
            <directory>src/main/resources</directory>
            <filtering>true</filtering>
            <includes>
                <include>**/*</include>
            </includes>
            <targetPath>META-INF/</targetPath>
        </resource>
        <resource>
            <directory>${project.build.directory}/dependency/</directory>
            <includes>
                <include>*.jar</include>
            </includes>
            <targetPath>lib/</targetPath>
        </resource>
    </resources>
<pluginManagement>
        <plugins>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-jar-plugin</artifactId>
                <configuration>
                    <archive>
                        <manifest>
                            <addClasspath>true</addClasspath>
                            <mainClass>${project.mainClass}</mainClass>
                            <classpathPrefix>lib/</classpathPrefix>
                        </manifest>

                        <manifestEntries>
                            <Rsrc-Main-Class>${project.realMainClass}  </Rsrc-Main-Class>
                            <Class-Path>./</Class-Path>
                        </manifestEntries>

                    </archive>
                </configuration>
            </plugin>
<plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-dependency-plugin</artifactId>
                <executions>
                    <execution>
                        <id>copy-dependencies</id>
                        <phase>package</phase>
                        <goals>
                            <goal>copy-dependencies</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </pluginManagement>
</build>
4
répondu Glaucio Southier 2015-10-28 16:01:39
        <!-- Method 1 -->
        <!-- Copy dependency libraries jar files to a separated LIB folder -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-dependency-plugin</artifactId>
            <configuration>
                <outputDirectory>${project.build.directory}/lib</outputDirectory>
                <excludeTransitive>false</excludeTransitive> 
                <stripVersion>false</stripVersion>
            </configuration>
            <executions>
                <execution>
                    <id>copy-dependencies</id>
                    <phase>package</phase>
                    <goals>
                        <goal>copy-dependencies</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        <!-- Add LIB folder to classPath -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-jar-plugin</artifactId>
            <version>2.4</version>
            <configuration>
                <archive>
                    <manifest>
                        <addClasspath>true</addClasspath>
                        <classpathPrefix>lib/</classpathPrefix>
                    </manifest>
                </archive>
            </configuration>
        </plugin>


        <!-- Method 2 -->
        <!-- Package all libraries classes into one runnable jar -->
        <plugin>
            <artifactId>maven-assembly-plugin</artifactId>
            <executions>
              <execution>
                <phase>package</phase>
                <goals>
                  <goal>single</goal>
                </goals>
              </execution>
            </executions>
            <configuration>
              <descriptorRefs>
                <descriptorRef>jar-with-dependencies</descriptorRef>
              </descriptorRefs>
            </configuration>
        </plugin>            
2
répondu Leslie Li 2018-03-21 05:39:45

en mettant Maven de côté, vous pouvez mettre des bibliothèques JAR à l'intérieur du bocal principal, mais vous aurez besoin d'utiliser votre propre classloader.

vérifier ce projet: un-JAR link text

1
répondu medopal 2009-11-13 13:56:40

ce post peut être un peu vieux, mais j'ai également eu le même problème récemment. La première solution proposée par John Stauffer est bonne, mais j'ai eu quelques problèmes en travaillant ce printemps. Les pots de dépendances du ressort que j'utilise ont quelques fichiers de propriétés et la déclaration xml-schemas qui partagent les mêmes chemins et noms. Bien que ces pots proviennent des mêmes versions, le jar-with-dependencies maven-but était d'écraser le fichier de thèses avec le dernier fichier trouvé.

à la fin, l'application n'a pas pu démarrer car les pots à ressorts ne pouvaient pas trouver les fichiers de propriétés corrects. Dans ce cas, la solution proposée par Rop ont résolu mon problème.

depuis, le projet spring-boot existe aussi. Il a une façon très cool de gérer ce problème en fournissant un objectif maven qui surchargent l'Objectif du paquet et fournir son propre chargeur de classe. Voir guide de référence des bottes à ressort

"
0
répondu Francois Gergaud 2014-11-08 18:18:55

Regardez cette réponse:

je crée un installateur qui fonctionne comme un fichier Java JAR et qui a besoin de déballer les fichiers WAR et JAR à des endroits appropriés dans le répertoire d'installation. Le plugin de dépendances peut être utilisé dans la phase de paquet avec le but de copie et il téléchargera n'importe quel fichier dans le dépôt Maven (y compris les fichiers de guerre) et les écrira où que vous en ayez besoin. J'ai changé le répertoire de sortie pour ${projet.construire.directory} / classes et ensuite le résultat final est que la tâche JAR normale inclut mes fichiers juste très bien. Je peux ensuite les extraire et de les écrire dans le répertoire d'installation.

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
    <execution>
        <id>getWar</id>
        <phase>package</phase>
        <goals>
            <goal>copy</goal>
        </goals>
        <configuration>
            <artifactItems>
                <artifactItem>
                    <groupId>the.group.I.use</groupId>
                    <artifactId>MyServerServer</artifactId>
                    <version>${env.JAVA_SERVER_REL_VER}</version>
                    <type>war</type>
                    <destFileName>myWar.war</destFileName>
                </artifactItem>
            </artifactItems>
            <outputDirectory>${project.build.directory}/classes</outputDirectory>
        </configuration>
    </execution>
</executions>

0
répondu millebi 2017-05-23 12:26:33

Merci J'ai ajouté ci-dessous snippet in POM.problème de fichier xml et de Mp résolu et créer le fichier fat jar qui inclut tous les pots dépendants.

<plugin>
    <artifactId>maven-assembly-plugin</artifactId>
        <executions>
            <execution>
                <phase>package</phase>
                <goals>
                    <goal>single</goal>
                </goals>
            </execution>
        </executions>
        <configuration>
            <descriptorRefs>
                <descriptorRef>dependencies</descriptorRef>
            </descriptorRefs>
        </configuration>
    </plugin>
</plugins>
0
répondu Rajeev Rathor 2016-10-17 09:36:09