Y compris les dépendances dans un pot avec Maven

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

J’ai un projet le construit dans un fichier jar unique. Je veux aussi que les classes des dépendances soient copiées dans le pot.

Mise à jour: je sais que je ne peux pas inclure un fichier jar dans un fichier jar. Je cherche un moyen de décompresser les fichiers JAR spécifiés en tant que dépendances et de regrouper les fichiers de classe dans mon fichier jar.

Vous pouvez le faire en utilisant le plugin maven-assembly avec le descripteur “jar-with-dependencies”. Voici le morceau pertinent de l’un de nos pom.xml qui fait ceci:

    maven-assembly-plugin   package  single      jar-with-dependencies      

Avec Maven 2, la bonne méthode consiste à utiliser le plug-in Maven2 Assembly qui contient 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 fichier exécutable, ajoutez simplement la classe principale à exécuter à la configuration du plugin:

  org.apache.maven.plugins maven-assembly-plugin    my.package.to.my.MainClass     

Si vous souhaitez créer cet assemblage dans le cadre du processus de génération normal, vous devez lier l’objective simple ou répertoire unique (l’objective de l’ assembly doit être exécuté UNIQUEMENT de la ligne de commande) à une phase du cycle de vie ( package approprié). ce:

  org.apache.maven.plugins maven-assembly-plugin   create-my-bundle package  single    jar-with-dependencies  ...     

Adaptez l’élément de configuration à vos besoins (par exemple, avec les éléments manifestes tels qu’ils sont prononcés).

Si vous souhaitez créer un fichier jar exécutable, vous devez également définir la classe principale. Donc, la configuration complète devrait être.

    maven-assembly-plugin   package  single        fully.qualified.MainClass    jar-with-dependencies     

Il y a le plugin d’ombre maven . Il peut être utilisé pour empaqueter et renommer les dépendances (omettre les problèmes de dépendance sur le chemin de classe).

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 consiste simplement à créer un projet WAR, même s’il ne s’agit que d’une application Java autonome que vous construisez:

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

  2. En outre, configurez un projet de guerre Maven (avec seulement un fichier src / main / webapp / WEB-INF / web.xml vide, ce qui évitera un avertissement / une erreur dans le maven-build), qui n’a que votre projet jar comme une dépendance, et faites de votre jar-project un dans votre projet de guerre. (Ce projet de guerre n’est qu’un simple truc pour envelopper toutes vos dépendances de fichiers jar dans un fichier zip.)

  3. Construire le projet de guerre pour produire le fichier de guerre.

  4. Dans l’étape de déploiement, renommez simplement votre fichier .war en * .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 caractère générique dans classpath fonctionne dans Java-6 ou supérieur)

Je pense que cela 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 la structure de l’application (vous verrez les numéros de version de tous les jars dépendants). éviter de tout colmater dans un seul fichier jar).

Vous pouvez utiliser le fichier jar nouvellement créé à l’aide d’une .

   your.group.id your.artifact.id 1.0 jar jar-with-dependencies   

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

Il existe trois méthodes courantes pour construire un JAR uber:

  1. Sans ombre Décompressez tous les fichiers JAR, puis remballez-les dans un seul JAR.
    • Pro: Fonctionne avec le chargeur de classes par défaut de Java.
    • Con: Les fichiers présents dans plusieurs fichiers JAR ayant le même chemin (par exemple, META-INF / services / javax.script.ScriptEngineFactory) vont se remplacer les uns les autres, entraînant un comportement défectueux.
    • Outils: Plugin Maven Assembly, Classworlds Uberjar
  2. Ombré Identique à non ombré, mais renommez (c’est-à-dire “ombrage”) tous les paquets de toutes les dépendances.
    • Pro: Fonctionne avec le chargeur de classes par défaut de Java. Evite certains conflits de versions (pas tous).
    • Con: Les fichiers présents dans plusieurs fichiers JAR ayant le même chemin (par exemple, META-INF / services / javax.script.ScriptEngineFactory) vont se remplacer les uns les autres, entraînant un comportement défectueux.
    • Outils: Maven Shade Plugin
  3. JAR de JAR. Le fichier JAR final contient les autres fichiers JAR intégrés.
    • Pro: évite les conflits de version de dépendance. Tous les fichiers de ressources sont conservés.
    • Con: Nécessite de regrouper un classloader spécial “bootstrap” pour permettre à Java de charger les classes à partir des fichiers JAR encapsulés. Le débogage des problèmes de chargeur de classe devient plus complexe.
    • Outils: Exporteur de fichiers JAR Eclipse, One-JAR.

Ma solution définitive sur Eclipse Luna et m2eclipse: Custom Classloader (téléchargez et ajoutez à votre projet, 5 classes uniquement): 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 du classloader à un jar et très rapide;

org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader my.Class

Modifier dans JIJConstants “Rsrc-Class-Path” en “Class-Path”
mvn clean dependency: package de dépendances de copie
est créé un pot avec des dépendances dans le dossier lib avec un chargeur de classe mince

    src/main/java  **/*.java **/*.properties    src/main/resources true  **/*  META-INF/   ${project.build.directory}/dependency/  *.jar  lib/      org.apache.maven.plugins maven-jar-plugin    true ${project.mainClass} lib/   ${project.realMainClass}  ./      org.apache.maven.plugins maven-dependency-plugin   copy-dependencies package  copy-dependencies        
     org.apache.maven.plugins maven-dependency-plugin  ${project.build.directory}/lib false false    copy-dependencies package  copy-dependencies       org.apache.maven.plugins maven-jar-plugin 2.4    true lib/        maven-assembly-plugin   package  single      jar-with-dependencies    

En mettant de côté Maven, vous pouvez placer des bibliothèques JAR dans le Jar principal, mais vous devrez utiliser votre propre chargeur de classes.

Vérifiez ce projet: texte de lien One-JAR

Ce post est peut-être un peu vieux, mais j’ai aussi eu le même problème récemment. La première solution proposée par John Stauffer est une bonne solution, mais j’ai eu quelques problèmes au spring. Les jars de dépendance du spring que j’utilise ont des fichiers de propriétés et une déclaration de schémas-xml qui partagent les mêmes chemins et noms. Bien que ces jars proviennent des mêmes versions, l’objective-maven jar-with-dependencies remplaçait ces fichiers par le dernier fichier trouvé.

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

Depuis lors, le projet Spring-Boot existe maintenant. C’est un moyen très pratique de gérer ce problème en fournissant un objective de maven qui surcharge l’objective du package et fournit son propre chargeur de classe. Voir le guide de référence

Regardez cette réponse:

Je crée un programme d’installation qui s’exécute en tant que fichier JAR Java et il doit décompresser les fichiers WAR et JAR aux emplacements appropriés du répertoire d’installation. Le plug-in de dépendance peut être utilisé dans la phase de package avec l’objective de copie et il télécharge tous les fichiers du référentiel Maven (y compris les fichiers WAR) et les écrit où vous en avez besoin. J’ai changé le répertoire de sortie en $ {project.build.directory} / classes et le résultat final est que la tâche JAR normale inclut très bien mes fichiers. Je peux alors les extraire et les écrire dans le répertoire d’installation.

  org.apache.maven.plugins maven-dependency-plugin   getWar package  copy     the.group.I.use MyServerServer ${env.JAVA_SERVER_REL_VER} war myWar.war   ${project.build.directory}/classes    

Merci d’avoir ajouté l’extrait ci-dessous dans le fichier POM.xml et le problème Mp résolu et de créer un fichier jar contenant tous les fichiers JAR dépendants.

  maven-assembly-plugin   package  single      dependencies