Comment puis-je créer un JAR exécutable avec des dépendances en utilisant Maven?
je veux empaqueter mon projet dans un seul pot exécutable pour la distribution.
Comment puis-je faire un paquet de projet Maven tous les pots de dépendances dans mon pot de sortie?
30 réponses
<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 but doit être ajouté avant l'assemblage:seul ou autrement le code sur votre propre projet n'est pas inclus.
Voir plus de détails dans les commentaires.
généralement, cet objectif est lié à une phase de construction à exécuter automatiquement. Cela garantit que le bocal est construit lors de l'exécution de mvn install
ou déploiement / libération.
<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>
vous pouvez utiliser le plugin de dépendances pour générer toutes les dépendances dans un répertoire séparé avant la phase du paquet et ensuite inclure cela dans le chemin de classe 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>
utilisez alternativement ${project.build.directory}/classes/lib
comme OutputDirectory pour intégrer tous les fichiers jar dans le bocal principal, mais alors vous aurez besoin d'ajouter du code de chargement de classe personnalisé pour charger les bocaux.
j'ai blogué sur différentes façons de le faire.
voir JAR exécutable avec Apache Maven (WordPress)
ou exécutable-jar-with-maven-exemple (GitHub)
Notes
ces avantages et inconvénients sont fournis par Stephan .
Pour Déploiement Manuel
- Pros
- Cons
- les dépendances sont hors du pot final.
Copie des Dépendances à un répertoire spécifique
<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>
Faire le Jar Exécutable et Classpath Conscient
<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>
à ce point le jar
est en fait exécutable avec des éléments externes classpath.
$ java -jar target/${project.build.finalName}.jar
Faire Déployable Archives
le fichier jar
n'est exécutable qu'avec le répertoire ...lib/
. Nous avons besoin de faire des archives pour se déployer avec le répertoire et son contenu.
<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>
Maintenant vous avez target/${project.build.finalName}.(zip|tar|tar.bz2|tar.gz)
qui contient chacun le jar
et lib/*
.
Apache Maven Assembly Plugin
- Pros
- Cons
- aucun soutien de déplacement de classe (utilisez maven-shade-plugin si le déplacement de classe est nécessaire).
<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>
vous avez target/${project.bulid.finalName}-jar-with-dependencies.jar
.
Apache Maven Shade Plugin
- Pros
- Cons
<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>
vous avez target/${project.build.finalName}-shaded.jar
.
onejar-maven-plugin
- Pros
- Cons
- Non activement soutenu depuis 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>
Printemps De Démarrage Plugin Maven
- Pros
- Cons
- ajouter des classes de ressorts et de bottes à ressort potentielles inutiles.
<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>
vous avez target/${project.bulid.finalName}-spring-boot.jar
.
prendre la réponse sans réponse et la 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 recommande d'en faire une partie naturelle de votre construction, plutôt que quelque chose à appeler explicitement. Pour en faire une partie intégrante de votre construction, ajoutez ce plugin à votre pom.xml
et liez-le à l'événement de cycle de vie package
. Cependant, un gotcha est que vous devez appeler le but assembly:single
si mettre cela dans votre pom.xml, alors que vous appelleriez 'assembly: assembly' si l'exécuter manuellement depuis 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>
utilisez le maven-shade-plugin pour empaqueter toutes les dépendances dans un uber-jar. Il peut également être utilisé pour construire un JAR exécutable en spécifiant la classe principale. Après avoir essayé d'utiliser maven-assembly et maven-jar , j'ai trouvé que ce plugin convenait le mieux à mes besoins.
j'ai trouvé ce plugin particulièrement utile car il fusionne le contenu de fichiers spécifiques 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 la le plugin tente d'empaqueter tous les fichiers de ressources
Voir 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>
longtemps utilisé le Maven Assemblée plugin , mais je n'ai pas pu trouver une solution au problème avec "already added, skipping"
. Maintenant, j'utilise un autre plugin - onejar-maven-plugin . L'exemple ci-dessous ( mvn package
construire en pot):
<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>
vous devez ajouter un dépôt pour ce plugin:
<pluginRepositories>
<pluginRepository>
<id>onejar-maven-plugin.googlecode.com</id>
<url>http://onejar-maven-plugin.googlecode.com/svn/mavenrepo</url>
</pluginRepository>
</pluginRepositories>
vous pouvez utiliser maven-dependency-plugin, mais la question était de savoir comment créer un JAR exécutable. Pour ce faire, il faut modifier comme suit la réponse de Matthew Franglen (btw, en utilisant le plugin de dépendances, il faut plus de temps pour construire à partir d'une cible propre):
<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>
une autre option si vous voulez vraiment reconditionner le contenu des autres bocaux à l'intérieur de votre seul bocal résultant est le plugin Maven Assembly plugin . Il décompresse et repasse tout dans un répertoire via <unpack>true</unpack>
. Ensuite, vous aurez un second passage qui en fera un énorme bocal.
une autre option est le plugin OneJar . Ceci exécute les actions de reconditionnement ci-dessus en une seule étape.
vous pouvez ajouter ce qui suit à votre 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>
ensuite, vous devez passer par la console au répertoire, où le pom.xml est localisé. Ensuite, vous devez exécuter mvn assembly: single et ensuite votre fichier JAR exécutable avec des dépendances sera construit avec un peu de chance. Vous pouvez le vérifier en passant au répertoire de sortie (cible) avec cd ./ cible et démarrage de votre Jarre avec une commande similaire à java-jar mavenproject1-1.0-SNAPSHOT-jar-with-dependencies.jar .
j'ai testé avec Apache Maven 3.0.3 .
vous pouvez combiner les maven-shade-plugin
et maven-jar-plugin
.
- le
maven-shade-plugin
regroupe vos classes et toutes les dépendances dans un seul fichier jar. - configurer le
maven-jar-plugin
pour spécifier la classe principale de votre jar exécutable (voir configurer le chemin de classe , chapitre"Make the Jar exécutable").
exemple de configuration POM pour 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>
enfin créer le jar exécutable en invoquant:
mvn clean package shade:shade
j'ai parcouru chacune de ces réponses en cherchant à faire un pot exécutable contenant toutes les dépendances et aucune d'entre elles n'a fonctionné correctement. La réponse est le plugin shade, son très simple et simple.
<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>
soyez conscient que vos dépendances doivent avoir une portée de compilation ou d'exécution pour que cela fonctionne correctement.
Ken Liu a raison à mon avis. Le plugin de dépendances maven vous permet d'étendre toutes les dépendances, que vous pouvez alors traiter comme des ressources. Cela vous permet de les inclure dans le Artéfact principal . L'utilisation de l'assemblée plugin crée un autre artefact qui peut être difficile à modifier - dans mon cas, je voulais ajouter des entrées manifeste. Mon nom finit par:
<project>
...
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<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>
<targetPath>/</targetPath>
</resource>
</resources>
</build>
...
</project>
voici un plugin JAR exécutable pour Maven que nous utilisons chez Credit Karma. Il crée un pot de pots avec un classloader capable de charger des classes à partir de pots imbriqués. Cela vous permet d'avoir la même classpath dans dev et prod et de garder toutes les classes dans un seul fichier jar signé.
https://github.com/creditkarma/maven-exec-jar-plugin
Et voici un blog avec des détails sur le plugin et pourquoi nous l'avons fait: https://engineering.creditkarma.com/general-engineering/new-executable-jar-plugin-available-apache-maven /
vous pouvez utiliser Maven-shade plugin pour construire un Uber jar comme ci-dessous""
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
</plugin>
utiliser onejar plugin pour le construire comme un fichier JAR exécutable qui empaquette tous les jarres de dépendance dans lui. Qui a résolu mon problème qui était semblable à cela. Quand assembly plugin a été utilisé, il a déballé tous les bocaux de dépendances dans le dossier source et les reconditionner comme un bocal, il avait Sur écrit toutes les implémentations similaires que j'avais à l'intérieur de mon code qui avaient les mêmes noms de classe. onejar est une solution facile ici.
Problème avec la localisation de partage de l'assemblée fichier avec maven-assembly-plugin-2.2.1?
essayez d'utiliser le paramètre de configuration des descripteurs au lieu des paramètres descripteurs/descripteur ou descriptorRefs/descriptorRef.
aucun D'eux ne fait ce dont vous avez besoin: recherchez le fichier sur classpath. Bien sûr, vous devez ajouter le paquet où l'Assemblée partagée se trouve sur classpath de maven-assembly-plugin (voir ci-dessous). Si vous utilisez Maven 2.x (Non Maven 3.x), vous aurez peut-être besoin d'ajouter cette dépendance dans le top-most parent pom.xml dans la section pluginManagement.
Voir ce pour plus de détails.
Class: org.apache.maven.plugin.Assemblée.io.Defaultassembllyreader
exemple:
<!-- Use the assembly plugin to create a zip file of all our dependencies. -->
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.2.1</version>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<descriptorId>assembly-zip-for-wid</descriptorId>
</configuration>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>cz.ness.ct.ip.assemblies</groupId>
<artifactId>TEST_SharedAssemblyDescriptor</artifactId>
<version>1.0.0-SNAPSHOT</version>
</dependency>
</dependencies>
</plugin>
il devrait en être ainsi:
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>unpack-dependencies</id>
<phase>generate-resources</phase>
<goals>
<goal>unpack-dependencies</goal>
</goals>
</execution>
</executions>
</plugin>
déballage doivent être dans la phase de production-ressources parce que, si dans la phase de paquet, ne sera pas inclus comme ressources. Essayez le paquet propre et vous verrez.
Je ne vais pas répondre directement à la question comme d'autres l'ont déjà fait avant, mais je me demande vraiment si c'est une bonne idée d'intégrer toutes les dépendances dans le bocal du projet lui-même.
je vois le point (facilité de déploiement / utilisation) mais cela dépend du cas d'utilisation de votre poject (et il peut y avoir des alternatives (voir ci-dessous)).
si vous l'utilisez seul, pourquoi pas.
Mais si vous utilisez votre projet dans d'autres contextes (comme dans une webapp, ou plongé dans un dossier où d'autres pots sont assis), vous pouvez avoir bocal de doublons dans votre classpath (ceux dans le dossier, l'un dans les pots). Peut-être pas une offre, mais j'évite ça.
une bonne alternative:
- déployez votre application comme un .zip. / la guerre : l'archive contient votre projet bocal et tous dépendants les pots ;
- utilisez un mécanisme de classloader dynamique (voir ressort, ou vous pouvez faites-le facilement vous - même) pour avoir un point d'entrée unique de votre projet (une seule classe pour démarrer-voir le mécanisme de manifeste sur une autre réponse), qui ajoutera (dynamiquement) à la classpath actuelle tous les autres pots nécessaires.
comme ceci, avec à la fin juste un manifeste et un "main spécial ClassLoader dynamique", vous pouvez commencer votre projet avec:
java -jar ProjectMainJar.jar com.stackoverflow.projectName.MainDynamicClassLoaderClass
si vous voulez si de la ligne de commande elle-même . Il suffit d'exécuter la commande ci-dessous à partir du chemin du projet
mvn de l'assemblée:l'assemblée
vous pouvez également utiliser ce plugin, il est assez bon et je l'utilise pour emballer mes pots http://sonatype.github.io/jarjar-maven-plugin/
quelque chose qui a fonctionné pour moi était:
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>unpack-dependencies</id>
<phase>prepare-package</phase>
<goals>
<goal>unpack-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/classes</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<executions>
<execution>
<id>unpack-dependencies</id>
<phase>package</phase>
</execution>
</executions>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
<mainClass>SimpleKeyLogger</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
j'ai eu un cas extraordinaire parce que ma dépendance était le système un:
<dependency>
..
<scope>system</scope>
<systemPath>${project.basedir}/lib/myjar.jar</systemPath>
</dependency>
j'ai changé le code fourni par @user189057 avec des modifications: 1) maven-dependency-plugin est exécuté en phase "prepare-package" 2) je suis en train d'extraire classess Non empaqueté directement sur "target / classes "
j'ai essayé la réponse la plus votée ici, et j'ai pu faire fonctionner le bocal. Mais le programme ne s'exécute pas correctement. Je ne sais pas quelle est la raison. Quand j'essaie d'exécuter à partir de Eclipse
, j'obtiens un résultat différent, mais quand j'exécute le jar depuis la ligne de commande j'obtiens un résultat différent (il s'écrase avec une erreur d'exécution spécifique au programme).
j'avais une exigence similaire à celle de L'OP juste que j'avais trop de dépendances (Maven) pour mon projet. Heureusement, le seul la solution qui a fonctionné pour moi était l'utilisation de Eclipse
. Très simple et très simple. Il ne s'agit pas d'une solution à L'OP, mais d'une solution pour quelqu'un qui a une exigence similaire, mais avec de nombreuses dépendances Maven,
1) cliquez avec le bouton droit de la souris sur le dossier de votre projet (dans Eclipse) et sélectionnez Export
2) Sélectionnez ensuite Java
-> Runnable Jar
3) Vous sera demandé de choisir l'emplacement du fichier jar
4) enfin, sélectionnez la classe qui a la méthode principale que vous voulez exécuter et choisissez Package dependencies with the Jar file
et cliquez sur Finish
C'est la meilleure façon que j'ai trouvée:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.4</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>com.myDomain.etc.MainClassName</mainClass>
<classpathPrefix>dependency-jars/</classpathPrefix>
</manifest>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.5.1</version>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>
${project.build.directory}/dependency-jars/
</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
avec cette configuration, toutes les dépendances seront localisées dans /dependency-jars
. Mon application n'a pas de classe Main
, juste des classes contextuelles, mais une de mes dépendances a une classe Main
( com.myDomain.etc.MainClassName
) qui démarre le serveur JMX, et reçoit un paramètre start
ou stop
. Ainsi, j'ai pu démarrer mon application comme ceci:
java -jar ./lib/TestApp-1.0-SNAPSHOT.jar start
j'attends qu'il soit utile pour vous tous.
pour résoudre ce problème, nous allons utiliser Maven Assembly Plugin qui va créer le JAR avec ses pots de dépendances dans un seul fichier JAR exécutable. Il suffit d'Ajouter ci-dessous la configuration du plugin dans votre pom.fichier xml.
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>com.your.package.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>
</pluginManagement>
</build>
après avoir fait cela, n'oubliez pas d'exécuter Maven tool avec cette commande mvn clean compiler assembly: single
le maven-assembly-plugin a bien fonctionné pour moi.
J'ai passé des heures avec le plugin Maven-dependency et je n'ai pas pu le faire fonctionner. La raison principale était que je devais définir dans la section de configuration explicitement les articles artéfacts qui devraient être inclus comme il est décrit dans la documentation .
Il y a un exemple là pour les cas où vous voulez l'utiliser comme: mvn dependency:copy
, où il n'y a pas inclus des artifactems mais il ne fonctionne pas.
cela pourrait aussi être une option,vous pourrez construire votre fichier jar""
<build>
<plugins>
<plugin>
<!-- Build an executable JAR -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.4</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
<mainClass>WordListDriver</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</build>
j'ai comparé les plugins arbre mentionnés dans ce post. J'ai généré 2 pots et un répertoire avec tous les pots. J'ai comparé les résultats et certainement le maven-ombre-plugin est le meilleur. Mon défi était que j'avais plusieurs ressources de printemps qui devaient être fusionnées, ainsi que jax-rs, et les services JDBC. Ils ont tous été fusionnés correctement par le plugin shade en comparaison avec le maven-assembly-plugin. Dans ce cas, le ressort échouera à moins que vous ne les copiez dans votre propre dossier de ressources et fusionner manuellement une fois. Les deux plugins affichent la bonne arborescence de dépendances. J'ai eu des scopes multiples comme test, provide, compile, etc le test et fourni ont été sautés par les deux plugins. Ils ont tous les deux produit le même manifeste mais j'ai pu consolider les licences avec le plugin shade en utilisant leur transformateur. Avec le maven-dependency-plugin bien sûr vous n'avez pas ces problèmes car les pots ne sont pas extraits. Mais comme d'autres l'ont fait, vous devez effectuer un fichier supplémentaire(s) de travail correctement. Voici une capture de la pom.xml
<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>
<includeScope>compile</includeScope>
<excludeTransitive>true</excludeTransitive>
<overWriteReleases>false</overWriteReleases>
<overWriteSnapshots>false</overWriteSnapshots>
<overWriteIfNewer>true</overWriteIfNewer>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.6</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>com.rbccm.itf.cdd.poller.landingzone.LandingZonePoller</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>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.4.3</version>
<configuration>
<shadedArtifactAttached>false</shadedArtifactAttached>
<keepDependenciesWithProvidedScope>false</keepDependenciesWithProvidedScope>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/services/javax.ws.rs.ext.Providers</resource>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/spring.factories</resource>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/spring.handlers</resource>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/spring.schemas</resource>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/spring.tooling</resource>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"/>
<transformer implementation="org.apache.maven.plugins.shade.resource.ApacheLicenseResourceTransformer">
</transformer>
</transformers>
</configuration>
<executions>
<execution>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
</plugin>
pour quiconque cherche des options pour exclure des dépendances spécifiques de l'uber-jar, c'est une solution qui a fonctionné pour moi:
<project...>
<dependencies>
<dependency>
<groupId>org.apache.spark</groupId>
<artifactId>spark-core_2.11</artifactId>
<version>1.6.1</version>
<scope>provided</scope> <=============
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<archive>
<manifest>
<mainClass>...</mainClass>
</manifest>
</archive>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
donc ce n'est pas une configuration de mvn-assembly-plugin mais une propriété de la dépendance.
il y a déjà des millions de réponses, je voulais ajouter que vous n'avez pas besoin de <mainClass>
si vous n'avez pas besoin d'ajouter un point d'entrée à votre application. par exemple, les IPA n'ont pas nécessairement la méthode main
.
Maven plugin config
<build>
<finalName>log-enrichment</finalName>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</plugin>
</plugins>
</build>
construire
mvn clean compile assembly:single
vérifier
ll target/
total 35100
drwxrwx--- 1 root vboxsf 4096 Sep 29 16:25 ./
drwxrwx--- 1 root vboxsf 4096 Sep 29 16:25 ../
drwxrwx--- 1 root vboxsf 0 Sep 29 16:08 archive-tmp/
drwxrwx--- 1 root vboxsf 0 Sep 29 16:25 classes/
drwxrwx--- 1 root vboxsf 0 Sep 29 16:25 generated-sources/
drwxrwx--- 1 root vboxsf 0 Sep 29 16:25 generated-test-sources/
-rwxrwx--- 1 root vboxsf 35929841 Sep 29 16:10 log-enrichment-jar-with-dependencies.jar*
drwxrwx--- 1 root vboxsf 0 Sep 29 16:08 maven-status/
ajouter à pom.xml:
<dependency>
<groupId>com.jolira</groupId>
<artifactId>onejar-maven-plugin</artifactId>
<version>1.4.4</version>
</dependency>
et
<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>
C'est ça. Le prochain paquet mvn va aussi créer un pot de graisse en plus, y compris tous les pots de dépendances.