Maven: Mes plugins préférés

Ayant beaucoup utilisé Maven ces derniers temps, j’ai dû faire pas mal de recherches pour lui faire faire ce que je voulais. Cela m’a permis de découvrir une série de plugins intéressants que je vous livre ici. De façon générale, il s’agit de plugins méconnus mais qui m’ont fait pousser un « Oh la bonne idée super pratique » lorsque je l’ai découvert. Avec un peu de chance, vous aurez la même réaction.

Évidemment, de nombreux autres plugins sont disponibles, utiles et bien faits. J’ai voulu focaliser ici sur mes nouvelles découvertes et sur les anciens qui sont revenus en grâce. Si vous recherchez un plugin, les deux points de départ sont http://maven.apache.org/plugins/ et http://mojo.codehaus.org/. Ensuite, Google est votre ami.

Débogage Maven

maven-help-plugin (org.apache.maven.plugins)

Plugin existant depuis toujours et s’étoffant tranquillement. Il permet d’avoir des informations sur un projet.

Buts préférés:
  • help:active-profiles – Liste de profils actifs pour ce build
  • help:effective-pom – Crée le pom résultant de la résolution des profils actifs, de héritage et des variables
  • help:evaluate – Permet d’évaluer une expression Maven (par exemple ${project.version}). Prend en considération les profils actifs

maven-dependency-plugin (org.apache.maven.plugins)

Un autre plugin relativement vieux. C’est le plugin ultime pour résoudre les problèmes de dépendances transitives.

Buts préférés:
  • dependency:tree – Vous donne un arbre de dépendances indiquant qui tire quoi et dans quel scope. Absolument indispensable pour faire le ménage

versions-maven-plugin (org.codehaus.mojo)

Mon tout nouveau plugin préféré. Il permet de gérer les versions d’un peu tout. En particulier, vous pourrez mettre à jour la version des poms enfants à partir de celle du pom parent. Vous pourrez aussi vérifier si les versions de vos dépendances et de vos plugins sont à les dernières disponibles. C’est un peu le plugin qu’on attendait depuis toujours.

Buts préférés:
  • versions:display-dependency-updates – List toutes les dépendances ayant une version plus récente
  • versions:display-plugin-updates – Liste tous les plugins ayant une version plus récente
  • versions:update-child-modules – Il faut tout d’abord changer la version du pom parent. En appelant ensuite ce goal sur le pom parent, il mettra à jour les versions dans enfants. Très pratique pour faire des changements de versions
  • versions:set – Comme update-child-modules mais permettant de spécifier la nouvelle version  en ligne de commande (-DnewVersion=VALUE) au lieu de changer le pom parent.

Packaging

maven-remote-resources-plugin (org.apache.maven.plugins)

Un plugin un peu obscur mais très utile pour partager des ressources entre plusieurs projets. Il permet de récupérer un « resource bundle » qui est en fait un jar avec un packaging particulier et disponible dans le repository maven. Le contenu de ce jar est filtré et ensuite intégré à l’artifact en cours de construction. Par exemple, pour un project sous license Apache, cela permet d’ajouter les fichiers au jar les fichiers requis par la licence (LICENSE, NOTICE, …). 

Buts préférés:
  • remote-resources:process – Le goal permettant d’intégrer le « resource bundle » à l’artifact courant

maven-license-plugin (com.mycila.maven-license-plugin)

Un autre plugin que j’ai récemment découvert et qui change la vie. Il permet de mettre le classique petit texte de copyright requis par une licence au haut de tous les fichiers du projet. Le formatera l’entête en fonction du type de fichier (<!– –> pour xml, # pour .properties, /* */ pour .java, etc.). Il y a aussi la possibilité de valider la présence de la licence durant la compilation.

Buts préférés:
  • license:format – Ajouter la licence à chaque fichier
  • license:check – Valide que la licence est correctement mise pour chaque fichier

maven-bundle-plugin (org.apache.felix)

J’aime bien aussi celui-là. Il transforme votre artifact en un bundle OSGi avec presque aucune configuration. Il n’y a pas de but explicite car il se lie lui-même à la phase prepare-package.

maven-shade-plugin (org.apache.maven.plugins)

Utiliser pour faire un uber jar, c’est-à-dire un jar agrégeant le contenu de plusieurs jars.  Pour ceux qui connaissent, il fait plus ou moins la même chose que jarjar pour lequel il n’existe pas de plugin Maven. Un exemple d’utilisation et la création d’un jar exécutable.

Buts préférés:
  • shade:shade – Effectue la « uberisation »

Divers

maven-timestamp-plugin (com.keyboardsamurais.maven)

Pas vraiment un plugin de reporting mais très utile pour en faire. En fait il comble un lacune de Maven qui est qu’il n’y a pas de variable pour la date. Donc ce plugin vous permet de mettre la date/heure dans des variables sous le format que vous voulez (SimpleDateFormat servant d’interpréteur). Vous pouvez donc utiliser ces variables par la suite.

Buts préférés:
  • timestamp:create – Pour créer une variable contenant la date. Il faut mettre plusieurs exécutions pour avoir plusieurs formats différents

Reporting

maven-clover2-plugin (com.atlassian.maven.plugins)

Donne un rapport Clover, c’est-à-dire un rapport complet de la converture du code par les tests. Il est relativement connu et je le mentionne ici pour indiquer qu’il est désormais activement maintenu par Atlassian et suit de très près les livraisons Clover. Il est aussi maintenant très étoffé et beaucoup plus facilement configurable qu’historiquement.

Buts préférés:
  • clover2:instrument – Effectue l’instrumentation du code
  • clover2:clover – Genère le rapport Clover
  • clover2:check – Vérifie que la couverture dépasse le pourcentage désiré

findbugs-maven-plugin (org.codehaus.mojo)

Autre plugin très connu qui souffrait d’un problème de maintenance dernièrement. Il semblerait que certaines personnes s’y sont penchés et il suis maintenant relativement correctement les mises à jour findbugs.

Buts préférés:
  • findbugs:findbugs – Génère le rapport findbugs. En général, on configure plutôt le plugin dans la section reporting du pom pour l’avoir au moment de la génération du site
  • findbugs:check – Fait planter le build si findbugs trouve des erreurs

Optimisation du build

Les dernières versions de Maven se sont en autres consacrées à l’amélioration de la productivité. Plusieurs options en ligne de commande ont été ajouté. Elles proviennent à peu près toute du maven-reactor-plugin qui a été redescendu au coeur de Maven. Il ne s’agit donc pas vraiment de plugins mais ça reste pratique de savoir qu’elles existent.

Nouvelles options:

  • –resume-from (-rf): Permet, pour un projet multi-module, de recommencer la compilation à partir d’un projet donné. Utile par exemple lorsque le build a échoué au milieu et que vous ne voulez pas reprendre du début.
  • –also-make (-am): Construire les projets mentionnés et leurs dépendances.
  • –also-make-dependents (-amd): Construire les projets mentionnés et les projets en dépendants.

Anciennes options:

  • –non-recursive (-N): Ne construire que le projet courant sans ses sous-modules. Surtout utile pour installer un pom parent ou bien faire tourner un plugin.
  • –file (-f): Utiliser le pom en paramètre et non le pom du répertoire courant. Cela va en pratique compiler un projet quelconque sans changer de répertoire (j’utilise surtout cette option dans des .bat utilitaires).
  • –projects (-pl): Construire les projets spécifiés en ligne de commande. Permet d’avoir un build très spécifique.

maven-reactor-plugin (org.apache.maven.plugins)

Comme mentionné plus haut, ce plugin n’est presque plus nécessaire (si vous utilisez une version Maven 2.1.x ou supérieure) car il a été intégré dans le coeur de Maven. Il reste toutefois un but intéressant. Ils n’ont pas pu le mettre à plus bas niveau car il dépend de fonctionnalités de SCM qui ne sont pas présentes dans le coeur.

Buts préférés:
  • reactor:make-scm-changes: Ne recompile que les projets (et les projets en dépendant) ayant des fichiers géré dans le SCM et modifiés localement. C’est assez magique comme optimisation car il ne recompile que ce qui est nécessaire. Faire attention toutefois, si votre SCM est un peu longuet à déterminer les changements locaux, cela peut parfois être plus long qu’un build en entier.