Maintenant que vous avez une meilleure vision du processus d'exécution d'un build Maven, nous allons pouvoir personnaliser la construction de votre projet grâce aux plugins maven.
Le but est d'adapter et d'enrichir le POM afin de coller le plus possible à votre besoin et ainsi d'automatiser au maximum la construction et la génération des livrables de votre projet.
Les plugins déjà câblés aux phases
Rappelez-vous : les phases d'un build lifecycle sont découpées en tâches réalisées par les goals de différents plugins : http://maven.apache.org/ref/3.5.0/maven-core/lifecycles.html.
Suivant le build lifecycle et le packaging utilisés, différents goals sont câblés par défaut aux différentes phases : http://maven.apache.org/ref/3.5.0/maven-core/default-bindings.html.
Pour le packaging JAR, voici le câblage par défaut (pour la version 3.5.0 de Maven) :
<phases>
<process-resources>
org.apache.maven.plugins:maven-resources-plugin:2.6:resources
</process-resources>
<compile>
org.apache.maven.plugins:maven-compiler-plugin:3.1:compile
</compile>
<process-test-resources>
org.apache.maven.plugins:maven-resources-plugin:2.6:testResources
</process-test-resources>
<test-compile>
org.apache.maven.plugins:maven-compiler-plugin:3.1:testCompile
</test-compile>
<test>
org.apache.maven.plugins:maven-surefire-plugin:2.12.4:test
</test>
<package>
org.apache.maven.plugins:maven-jar-plugin:2.4:jar
</package>
<install>
org.apache.maven.plugins:maven-install-plugin:2.4:install
</install>
<deploy>
org.apache.maven.plugins:maven-deploy-plugin:2.7:deploy
</deploy>
</phases>
Affiner la configuration de la compilation
J'aimerais que lors de la compilation, Maven m'affiche les utilisations de méthodes dépréciées (@Deprecated
) ainsi que les avertissements de compilation (warnings).
Je remarque dans la documentation que la phase compile
est assurée par le goal compile
du plugin org.apache.maven.plugins:maven-compiler-plugin
:
<phases>
...
<compile>
org.apache.maven.plugins:maven-compiler-plugin:3.1:compile
</compile>
...
</phases>
Je vais dans la documentation des plugins : https://maven.apache.org/plugins/index.html.
Et plus précisément dans la documentation du goal compile
du plugin maven-compiler-plugin
: https://maven.apache.org/plugins/maven-compiler-plugin/compile-mojo.html.
J'obtiens ainsi une description du goal et la liste des options de configuration qui lui sont applicables.
Deux options retiennent mon attention :
Name | Type | Description |
---|---|---|
showDeprecation |
| Sets whether to show source locations where deprecated APIs are used. |
showWarnings |
| Set to true to show compilation warnings. |
Par défaut, ces deux options sont à false
. Pour les activer, il y a deux solutions :
soit en ajoutant une section
<configuration>
dans la définition du plugin dans le POM :<project> ... <!-- =============================================================== --> <!-- Build --> <!-- =============================================================== --> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.1</version> <configuration> <showDeprecation>true</showDeprecation> <showWarnings>true</showWarnings> </configuration> </plugin> </plugins> </build> ... </project>
soit en utilisant les propriétés données par les lignes « User property is: ... » :
<project> ... <!-- =============================================================== --> <!-- Propriétés --> <!-- =============================================================== --> <properties> <maven.compiler.showDeprecation>true</maven.compiler.showDeprecation> <maven.compiler.showWarnings>true</maven.compiler.showWarnings> </properties> ... </project>
Définir la classe Main du JAR
Dans la première partie nous avions déjà vu comment définir la classe Main dans le manifest du JAR généré par Maven.
Si je reprends le même principe que dans la section précédente, voici comment j'en suis arrivé à cette configuration.
Dans la documentation, la phase
package
est assurée par le goaljar
du pluginorg.apache.maven.plugins:maven-jar-plugin
:<phases> ... <package> org.apache.maven.plugins:maven-jar-plugin:2.4:jar </package> ... </phases>
Je vais dans la documentation du goal
jar
du pluginmaven-jar-plugin
: https://maven.apache.org/plugins/maven-jar-plugin/jar-mojo.html.Je repère l'option
archive
qui me renvoie à la documentation de Maven Archiver où j'obtiens les éléments de configuration du manifest : http://maven.apache.org/shared/maven-archiver/index.html#class_manifest.J'en déduis la configuration adéquate et je l'ajoute au POM :
<project> ... <!-- =============================================================== --> <!-- Build --> <!-- =============================================================== --> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jar-plugin</artifactId> <version>3.0.2</version> <configuration> <archive> <manifest> <mainClass>org.exemple.demo.App</mainClass> </manifest> </archive> </configuration> </plugin> </plugins> </build> ... </project>
Gérer les plugins de manière globale
Il est fortement recommandé de définir les versions des plugins utilisés.
Comme pour les dépendances, il est possible de le faire de manière globale au projet via la section <pluginManagement>
dans le POM parent. Vous pouvez ainsi fixer les versions des plugins mais aussi leur configuration de manière globale.
Si je reprends les exemples précédents, voici ce que j'obtiens dans le POM parent :
<project>
...
<!-- =============================================================== -->
<!-- Build -->
<!-- =============================================================== -->
<build>
<!-- ===== Gestion des plugins ===== -->
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<showDeprecation>true</showDeprecation>
<showWarnings>true</showWarnings>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.0.2</version>
</plugin>
</plugins>
</pluginManagement>
</build>
...
</project>
Et dans mon module, il ne me reste plus que :
<project>
...
<!-- =============================================================== -->
<!-- Build -->
<!-- =============================================================== -->
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>org.exemple.demo.App</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</build>
...
</project>
Ajouter de nouveaux plugins dans les phases
J'ai défini 3 profils permettant de spécifier l'environnement cible de ma construction (développement, test, production) :
<project>
...
<!-- =============================================================== -->
<!-- Profils -->
<!-- =============================================================== -->
<profiles>
<!-- Profil pour l'environnement de développement -->
<profile>
<id>target-dev</id>
...
</profile>
<!-- Profil pour l'environnement de test -->
<profile>
<id>target-test</id>
...
</profile>
<!-- Profil pour l'environnement de production -->
<profile>
<id>target-prod</id>
...
</profile>
</profiles>
...
</project>
Lors du build avec Maven, je veux m'assurer qu'au moins un des profils est activé. Je vais pour cela utiliser le goal enforce
du plugin maven-enforcer-plugin
: https://maven.apache.org/enforcer/maven-enforcer-plugin/.
J'ajoute donc ce plugin. Il faut aussi que je câble son goal enforce à la phase validate du build lifecycle default. Cela se fait grâce à la section <executions>
:
<project>
...
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<version>1.4.1</version>
<executions>
<execution>
<!-- je choisis un nom unique pour définir cette exécution -->
<id>enforce-profile-target</id>
<!-- je branche l'exécution à la phase "validate" -->
<phase>validate</phase>
<!-- cette exécution lancera le goal "enforce" -->
<goals>
<goal>enforce</goal>
</goals>
<!-- La configuration du plugin propre à cette exécution -->
<configuration>
<rules>
<requireActiveProfile>
<profiles>target-dev,target-test,target-prod</profiles>
<all>false</all>
</requireActiveProfile>
</rules>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
...
</project>
Si je lance maintenant mon build sans activer de profil target-...
cela me renvoie une erreur :
$ mvn package ... [WARNING] Rule 0: org.apache.maven.plugins.enforcer.RequireActiveProfile failed with message: Il faut activer un des profils target Profile "target-dev" is not activated. Profile "target-test" is not activated. Profile "target-prod" is not activated. ... BUILD FAILURE
Alors qu'en activant un des profils, je n'ai plus de problème :
$ mvn package -Ptarget-dev ... BUILD SUCCESS
Conclusion
Maven fournit un certain nombre de plugins de base. Suivant le build lifecycle et le packaging utilisés, différents goals de ces plugins sont câblés par défaut aux différentes phases :
http://maven.apache.org/ref/3.5.0/maven-core/default-bindings.html
http://maven.apache.org/ref/3.5.0/maven-core/lifecycles.html
Référez-vous à la documentation des plugins pour trouver le plugin qu'il vous faut et connaître son fonctionnement.
Il est fortement recommandé de définir les versions des plugins utilisés.
Comme pour les dépendances, il est possible de gérer les plugins de manière globale au projet via la section <pluginManagement>
dans le POM parent.
Vous pouvez câbler des nouveaux goals aux phases grâce aux sections <executions>
des plugins.
Dans le prochain chapitre, je vous montrerai comment utiliser les plugins pour parfaire le packaging de vos livrables.