Je souhaite regrouper mon projet dans un seul fichier JAR exécutable pour distribution.
Comment puis-je faire un package de projet Maven tous les fichiers JAR de dépendance dans mon fichier JAR de sortie?
Je souhaite regrouper mon projet dans un seul fichier JAR exécutable pour distribution.
Comment puis-je faire un package de projet Maven tous les fichiers JAR de dépendance dans mon fichier JAR de sortie?
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
L'objectif de compilation doit être ajouté avant l'assemblage: seul ou sinon le code de 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 génération pour s'exécuter automatiquement. Cela garantit que le fichier JAR est créé lors de l'exécution mvn install
ou de l'exécution d'un déploiement / d'une version.
<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>
mvn clean compile assembly:single
.
<appendAssemblyId>false</appendAssemblyId>
dans le configuration
pour éviter le suffixe ennuyeux "-jar-with-dependencies" dans le nom
compile
et vous êtes foutu.
Vous pouvez utiliser le plug-in de dépendance pour générer toutes les dépendances dans un répertoire distinct avant la phase de package, puis l'inclure 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>
Vous pouvez également utiliser ${project.build.directory}/classes/lib
comme OutputDirectory pour intégrer tous les fichiers jar dans le jar principal, mais vous devrez ensuite ajouter du code de chargement de classe personnalisé pour charger les jars.
${project.build.directory}/classes/lib
as outputDirectory
pour avoir un .jar principal avec toutes les dépendances à l'intérieur, mais - Comment ajouter du code de chargement de classe personnalisé pour charger ces pots? Je dois faire l' exécution du travail comme: java -jar main-jar-with-deps.jar
. Est-ce possible ?
J'ai blogué sur différentes façons de le faire.
Voir Pot exécutable avec Apache Maven (WordPress)
ou un exécutable-pot-avec-maven-exemple (GitHub)
Ces avantages et inconvénients sont fournis par Stephan .
<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>
<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 stade, le jar
est réellement exécutable avec des éléments de chemin de classe externes.
$ java -jar target/${project.build.finalName}.jar
Le jar
fichier n'est exécutable qu'avec le ...lib/
répertoire frère . Nous devons créer des archives à déployer avec l'annuaire 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)
chacun contenant le jar
et lib/*
.
<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
.
<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
.
<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>
<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
.
Prenant la réponse d'Unanswered et la reformatant, 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 recommanderais d'en faire une partie naturelle de votre build, plutôt que quelque chose à appeler explicitement. Pour en faire une partie intégrante de votre build, ajoutez ce plugin à votre pom.xml
et liez-le à l' package
événement du cycle de vie. Cependant, un problème est que vous devez appeler l' assembly:single
objectif si vous mettez cela dans votre pom.xml, tandis que vous appelleriez 'assembly: assembly' si vous l'exécutez 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>
Utilisez le plug-in maven-shadow pour regrouper toutes les dépendances dans un seul uber-jar. Il peut également être utilisé pour créer un fichier 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. Cela est nécessaire lorsqu'il existe des fichiers de ressources portant le même nom dans les bocaux et que le plug-in essaie de regrouper 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>
J'ai longtemps utilisé le plugin d'assemblage maven , mais je n'ai pas pu trouver de solution au problème "already added, skipping"
. Maintenant, j'utilise un autre plugin - onejar-maven-plugin . Exemple ci-dessous ( mvn package
build jar):
<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 référentiel 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 le plugin maven-dependency-plugin, mais la question était de savoir comment créer un JAR exécutable. Pour ce faire, il faut apporter la modification suivante à la réponse de Matthew Franglen (btw, l'utilisation du plug-in de dépendance prend plus de temps à créer lors du démarrage à 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>
Vous pouvez utiliser le plugin maven-shadow pour construire un pot Uber 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>
Une autre option si vous voulez vraiment reconditionner les autres contenus JAR dans votre seul JAR résultant est le plugin Maven Assembly . Il décompresse puis reconditionne tout dans un répertoire via <unpack>true</unpack>
. Ensuite, vous auriez un deuxième passage qui l'a intégré dans un JAR massif.
Une autre option est le plugin OneJar . Cela effectue 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 basculer via la console vers le répertoire, où se trouve le pom.xml. Ensuite, vous devez exécuter mvn assembly: single , puis votre fichier JAR exécutable avec les dépendances sera, espérons-le, construit. Vous pouvez le vérifier lorsque vous passez au répertoire de sortie (cible) avec cd ./target et que vous démarrez votre jar avec une commande similaire à java -jar mavenproject1-1.0-SNAPSHOT-jar-with-dependencies.jar .
J'ai testé cela avec Apache Maven 3.0.3 .
J'ai parcouru chacune de ces réponses en cherchant à créer un gros fichier exécutable contenant toutes les dépendances et aucune ne fonctionnait correctement. La réponse est le plugin d'ombre, c'est très simple et direct.
<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>
N'oubliez pas que vos dépendances doivent avoir une portée de compilation ou d'exécution pour que cela fonctionne correctement.
plugin
élément entre en pom.xml
dessous build/plugins
.
Vous pouvez combiner le maven-shade-plugin
et maven-jar-plugin
.
maven-shade-plugin
packs vos classes et toutes les dépendances dans un seul fichier jar.maven-jar-plugin
pour spécifier la classe principale de votre fichier exécutable (voir Configurer le chemin de classe , chapitre "Créer le fichier 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éez le fichier exécutable en appelant:
mvn clean package shade:shade
Ken Liu a raison à mon avis. Le plugin de dépendance maven vous permet d'étendre toutes les dépendances, que vous pouvez ensuite traiter comme des ressources. Cela vous permet de les inclure dans l' artefact principal . L'utilisation du plugin d'assemblage crée un artefact secondaire qui peut être difficile à modifier - dans mon cas, je voulais ajouter des entrées de manifeste personnalisées. Mon pom a fini 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>
Ça devrait être comme ça:
<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>
Le déballage doit être en phase de génération de ressources car, s'il est en phase de package, il ne sera pas inclus en tant que ressources. Essayez un emballage propre et vous verrez.
Un problème avec la localisation du fichier d'assembly partagé avec maven-assembly-plugin-2.2.1?
Essayez d'utiliser le paramètre de configuration descriptorId au lieu des paramètres descriptors / descriptor 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 package dans lequel l'assembly partagé réside dans le chemin de classe de maven-assembly-plugin (voir ci-dessous). Si vous utilisez Maven 2.x (pas Maven 3.x), vous devrez peut-être ajouter cette dépendance dans pom.xml parent le plus haut dans la section pluginManagement.
Voir ceci pour plus de détails.
Classe: org.apache.maven.plugin.assembly.io.DefaultAssemblyReader
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>
Pour résoudre ce problème, nous utiliserons le plug-in d'assemblage Maven qui créera le fichier JAR avec ses fichiers JAR de dépendance dans un seul fichier JAR exécutable. Ajoutez simplement la configuration du plugin ci-dessous dans votre fichier pom.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 cela, n'oubliez pas d'exécuter l'outil MAVEN avec cette commande mvn clean compile assembly: single
Je ne répondrai pas directement à la question car d'autres l'ont déjà fait auparavant, mais je me demande vraiment si c'est une bonne idée d'incorporer toutes les dépendances dans le pot du projet lui-même.
Je vois le point (facilité de déploiement / utilisation) mais cela dépend du cas d'utilisation de votre projet (et il peut y avoir des alternatives (voir ci-dessous)).
Si vous l'utilisez de manière totalement autonome, pourquoi pas.
Mais si vous utilisez votre projet dans d'autres contextes (comme dans une webapp, ou déposé dans un dossier où se trouvent d'autres pots), vous pouvez avoir des doublons de pots dans votre chemin de classe (ceux du dossier, celui des pots). Peut-être pas un accord d'enchère, mais j'évite généralement cela.
Une bonne alternative:
Comme ça, avec au final juste un manifeste et un "chargeur de classe dynamique spécial principal", vous pouvez démarrer votre projet avec:
java -jar ProjectMainJar.jar com.stackoverflow.projectName.MainDynamicClassLoaderClass
Pour créer un fichier JAR exécutable à partir de la ligne de commande elle-même, exécutez simplement la commande ci-dessous à partir du chemin du projet:
mvn assembly:assembly
pom.xml
cas contraire Error reading assemblies: No assembly descriptors found.
. C'est ce qui m'arrive de toute façon.
C'est le meilleur moyen que j'ai trouvé:
<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 situées dans /dependency-jars
. Mon application n'a pas de Main
classe, juste des contextes, mais l'une de mes dépendances a une Main
classe ( com.myDomain.etc.MainClassName
) qui démarre le serveur JMX et reçoit un start
ou un stop
paramètre. Donc, avec cela, j'ai pu démarrer mon application comme ceci:
java -jar ./lib/TestApp-1.0-SNAPSHOT.jar start
J'attends que ce soit utile pour vous tous.
J'ai comparé les plugins d'arbre mentionnés dans cet article. J'ai généré 2 pots et un répertoire avec tous les pots. J'ai comparé les résultats et le plugin maven-shadow est certainement le meilleur. Mon défi était que j'avais plusieurs ressources de printemps qui devaient être fusionnées, ainsi que des services jax-rs et JDBC. Ils ont tous été fusionnés correctement par le plugin d'ombre en comparaison avec le plugin maven-assembly-plugin. Dans ce cas, le ressort échouera, sauf si vous les copiez dans votre propre dossier de ressources et les fusionnez manuellement une fois. Les deux plugins produisent l'arborescence de dépendances correcte. J'ai eu plusieurs étendues comme tester, fournir, compiler, etc. le test et fourni ont été ignorés par les deux plugins. Ils ont tous deux produit le même manifeste, mais j'ai pu consolider les licences avec le plugin d'ombre à l'aide de leur transformateur. Avec le plugin maven-dependency, bien sûr que vous ne le faites pas t ont ces problèmes car les pots ne sont pas extraits. Mais comme certains l'ont souligné, vous devez transporter un ou plusieurs fichiers supplémentaires pour fonctionner correctement. Voici un aperçu du fichier 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>
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 un système:
<dependency>
..
<scope>system</scope>
<systemPath>${project.basedir}/lib/myjar.jar</systemPath>
</dependency>
J'ai changé le code fourni par @ user189057 avec des changements: 1) le plugin maven-dependency est exécuté dans la phase "prepare-package" 2) J'extrais directement les classes décompressées vers "target / classes"
J'ai essayé la réponse la plus votée ici et j'ai pu obtenir le pot exécutable. Mais le programme ne s'est pas exécuté correctement. Je ne connais pas la raison. Quand j'essaye de fuirEclipse
, j'obtiens un résultat différent, mais lorsque j'exécute le pot à partir de la ligne de commande, j'obtiens un résultat différent (il se bloque 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, la seule solution qui a fonctionné pour moi était celle de l'utilisation Eclipse
. Très simple et très simple. Ce n'est pas une solution à l'OP mais c'est une solution pour quelqu'un qui a une exigence similaire mais avec de nombreuses dépendances Maven,
1) Cliquez avec le bouton droit sur votre dossier de projet (dans Eclipse) et sélectionnez Export
2) Sélectionnez ensuite Java
->Runnable Jar
3) Il vous sera demandé de choisir l'emplacement du fichier jar
4) Enfin, sélectionnez la classe qui a la méthode Main que vous souhaitez exécuter et choisissez Package dependencies with the Jar file
et cliquez surFinish
Cela pourrait également être une option, vous pourrez créer 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>
Pour tous ceux qui recherchent des options pour exclure des dépendances spécifiques de l'uber-jar, voici 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>
Ce n'est donc pas une configuration du 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 <mainClass>
si vous n'avez pas besoin d'ajouter entryPoint à votre application. Par exemple, les API peuvent ne pas avoir nécessairement de main
méthode.
<build>
<finalName>log-enrichment</finalName>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</plugin>
</plugins>
</build>
mvn clean compile assembly:single
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/
Ajoutez à 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 créera également un gros pot en plus, y compris tous les pots de dépendance.
Le plugin maven-assembly-plug a très 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 explicitement dans la section de configuration les éléments d'artefact qui devraient être inclus comme cela est décrit dans la documentation . Il y a un exemple pour les cas où vous souhaitez l'utiliser comme:, mvn dependency:copy
où il n'y a pas d'artefactItems inclus mais cela ne fonctionne pas.
Ce billet de blog montre une autre approche avec la combinaison des plugins maven-jar et maven-assembly. Avec le xml de configuration d'assembly du billet de blog, il peut également être contrôlé si les dépendances seront développées ou simplement collectées dans un dossier et référencées par une entrée classpath dans le manifeste:
La solution idéale consiste à inclure les fichiers jars dans un dossier lib et le fichier manifest.mf du fichier jar principal inclut tous les fichiers jars dans classpath.
Et c'est exactement celui-là qui est décrit ici: https://caffebig.wordpress.com/2013/04/05/executable-jar-file-with-dependent-jars-using-maven/
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.4.1</version>
<configuration>
<!-- get all project dependencies -->
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<!-- bind to the packaging phase -->
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
D'accord, c'est donc ma solution. Je sais qu'il n'utilise pas le fichier pom.xml. Mais j'ai eu le problème de compilation et d'exécution de mon programme sur Netbeans mais il a échoué lorsque j'ai essayé Java -jar MyJarFile.jar. Maintenant, je ne comprends pas bien Maven et je pense que cela a eu du mal à obtenir que Netbeans 8.0.2 inclue mon fichier jar dans une bibliothèque pour les mettre dans un fichier jar. Je pensais à la façon dont j'utilisais les fichiers jar sans Maven dans Eclipse.
C'est Maven qui peut compiler toutes les dépendances et tous les plugins. Pas Netbeans. (Si vous pouvez obtenir Netbeans et pouvoir utiliser java .jar pour ce faire, dites-moi comment (^. ^) V)
[Résolu - pour Linux] en ouvrant un terminal.
alors
cd /MyRootDirectoryForMyProject
Prochain
mvn org.apache.maven.plugins:maven-compiler-plugin:compile
Prochain
mvn install
Cela créera un fichier jar dans le répertoire cible.
MyJarFile-1.0-jar-with-dependencies.jar
Maintenant
cd target
(Vous devrez peut - être exécuter: chmod +x MyJarFile-1.0-jar-with-dependencies.jar
)
et enfin
java -jar MyJarFile-1.0-jar-with-dependencies.jar
S'il te plait regarde
https://cwiki.apache.org/confluence/display/MAVEN/LifecyclePhaseNotFoundException
Je publierai cette solution dans quelques autres pages avec un problème similaire. J'espère pouvoir sauver quelqu'un d'une semaine de frustration.