Apache Maven

str

TODO

Article lu   fois.

Les deux auteurs

Liens sociaux

Viadeo Twitter Facebook Share on Google+   

I. Préface de la troisième édition

Image non disponible

Ecrire un bouquin pour un éditeur est un travail épuisant. La rédaction elle même n'est qu'une toute petite partie du travail, déjà prenante, et il faut y ajouter les relations éditeur par eMail et la phase de relecture puis de mise en page, sans parler des questions des équipes marketing pour la promotion du livre.

Pour la première édition de ce livre je découvrais le monde de l'édition et j'étais super motivé. Nous avons nous-même choisi nos relecteurs dans la communauté Maven francophone et utilisé un DropBox, nettement plus pratique que le process d'envoi des chapitres par eMail proposé par l'éditeur.

Il a fallu aussi s'adapter au template Word de Pearson, qui s'est avéré pas si mal fait que ça après avoir été confronté à celui d'autres éditeurs ! Au final, la masse de travail, toutes les tâches non prévues, pour quelques euros récoltés (8% à se partager) n'est pas du tout rentable. Si cela restait du plaisir - après tout, écrire du code OSS n'est pas très rentable non plus - la pillule pourrait passer, mais en plus il faut subir les contraintes de la chaîne d'édition.

Pearson nous a annoncé début décembre 2013 que le livre serait arrêté, faute de rentabilité. Pas vraiment une surprise, un livre technique, qui plus est en Français, n'a pas un auditoire énorme - ou alors, peut être que tout le monde fait du gradle aujourd'hui - en tout cas nous en avons vendu environ 2000 exemplaires, ce qui est un beau succès pour un marché aussi limité.

Aussi, après avoir récupéré nos droits sur le texte nous avons décidé de le convertir en AsciiDoc pour ne plus subir Word et le template editeur, et surtout de l'open-sourcer, sous license Creative Commons 4.0 afin que tout le monde en profite et que d'éventuels contributeurs puisse nous aider à corriger les boulettes inévitables qui s'y sont glissées.

Image non disponible "Attribution - Pas d'Utilisation Commerciale - Partage dans les Mêmes Conditions"

Nicolas de Loof

II. Préface de la seconde édition

Image non disponible

La rédaction de la première édition d'Apache Maven a été un exercice difficile mais très enrichissant. Avec Arnaud, nous avons trouvé un rythme et un ton qui nous permettait de prendre du plaisir sans accumuler trop de retard - un petit mois à peine - sur le planning de Pearson. Nous en avons retiré une grande fierté, surtout avec le très bon accueil du public.

Malgré cela, nous avons rapidement identifié des manques et des sujets que nous aurions aimé approfondir. Au cours de la rédaction, les nouvelles versions de plugins et l'avancement des développements de Maven 3 rendaient certaines de nos remarques obsolètes ou moins pertinentes. La liste des éléments de notre Erratum, que nous n'avons jamais publié d'ailleurs faute de l'organiser correctement, a commencé à s'allonger. Il était hors de question d'en rester là !

A l'heure où nous reprenons la plume (enfin, le clavier), Maven 3 enfin sorti en version 3.0 finale, est pleinement utilisable sur un projet. Les versions suivantes apporteront encore de nouvelles fonctionnalités et améliorations. Dans le même temps, de nombreux projets vont continuer d'utiliser Maven 2 pendant encore un long moment. Il n'est pas question de laisser ces utilisateurs sur le carreau juste parce que la nouvelle version de Maven est plus belle, plus grande, plus forte.

Nous avons donc choisi de donner à cette seconde édition une double lecture : le corps du texte a été revu pour correspondre à l'état de l'art, à savoir Maven 3. De nouveaux chapitres viennent en décrire les avancées et les outils associés. C'est seulement lorsqu'une rupture significative avec les versions précédentes existe que nous ajoutons un encart. Ces encarts sont reconnaissables au logo :

Image non disponible

Vous constaterez rapidement qu'ils sont assez peu nombreux : Maven 3 est avant tout conçu pour remplacer son prédécesseur sans heurts. Même avec ces réserves, les grandes idées présentées dans le livre sont applicables aux deux versions. Nous espérons donc que vous en tirerez le meilleur parti.

Quoi qu'il en soit, nous avons utilisé Maven 3.0 dans ses diverses pré-versions et nous vous encourageons à migrer vers cette nouvelle édition de l'outil phare du développement Java. Les prochaines versions sont une large promesse de fonctionnalités innovantes, et « au pire » vous bénéficierez d'une amélioration des performances et d'une réduction d'occupation mémoire ! Si vous utiliser m2eclipse pour intégrer votre projet Maven dans Eclipse, vous êtes déjà des utilisateurs de Maven 3 sans même le savoir, alors laissez vos dernières hésitations de côté et en avant toute.

Nous espérons que les pages qui suivent vous aideront à prendre en main Maven et à en comprendre la richesse et la philosophie, qui en font un outil sans équivalent.

III. Avant-propos

Image non disponible

L'écriture d'un ouvrage technique n'est pas une tâche triviale, car il est facile de perdre le lecteur dans une avalanche de concepts théoriques ou de s'égarer dans des détails non fondamentaux. Décrire un outil comme Maven, ou tout simplement le définir clairement, tout en restant accessible à tous, est encore plus délicat : soit on reste trop vague, et le lecteur n'a plus qu'à attendre le Chapitre 5 pour commencer à apprendre quelque chose de concret, soit on s'embarque dans de longues explications de principes et de concepts et le lecteur n'attendra jamais ce même Chapitre 5.

Pour être honnête, je dois dire que les premières ébauches de cet ouvrage sont immanquablement tombées dans ces travers, ce qui annonçait un livre bien peu pertinent pour les utilisateurs, qu'ils soient novices ou déjà expérimentés. Lorsque j'ai soumis les premiers extraits de ce projet à Arnaud, il m'en a rapidement fait la remarque et nous nous sommes accordés sur la forme que nous voulions donner à ce livre.

Mon objectif est de communiquer ma passion autour de ce projet open-source qu'est Maven, lequel réunit des développeurs aux parcours très différents. Les rencontres que j'ai faites dans cette communauté ont forgé mon approche de l'informatique. Avec cette motivation, établir un dictionnaire impersonnel Maven-Français était exclu ; aussi j'ai rapidement choisi, en accord avec Arnaud, de privilégier une approche aussi didactique que possible, bâtie sur des exemples concrets issus de ma propre expérience du terrain.

Il est difficile de sensibiliser les utilisateurs aux enjeux que Maven tente de gérer, alors qu'ils y sont pourtant confrontés en permanence. Situation intéressante où tout le monde rencontre un problème, mais, faute de mettre un nom dessus et d'en évaluer l'importance, celui-ci reste latent tout au long de la vie du projet, amenant parfois à des situations critiques. Nous allons suivre ensemble la vie d'un projet fictif, bien que largement inspiré de situations réelles. Il passera par toutes les phases, du prototype écrit sur un coin de table à l'application stratégique d'entreprise de grande envergure, ce qui nous permettra de couvrir un très large éventail de situations.

Plutôt que de décrire le rôle de Maven sur un projet, ou de vous accabler par un long exposé théorique sur ses concepts, je préfère au travers de cette démonstration un peu romancée vous montrer les difficultés concrètes auxquelles Maven s'attaque. Sur la base de ces exemples, parfois volontairement excessifs, je souhaite vous démontrer de manière ludique les avantages que Maven peut apporter à vos projets. Malgré les caricatures proposées, de nombreuses situations vous sembleront familières. Derrière la fiction se cachent des cas bien réels, que je n'ai fait qu'amplifier, et beaucoup auront des points communs avec vos propres difficultés. Ce parallèle vous donnera une image réaliste de Maven et des conseils applicables dans les meilleurs délais.

J'espère que vous apprécierez ce choix et que vous tirerez un enseignement pratique du texte qui suit. En particulier, j'aimerais qu'arrivé au bout de votre lecture vous soyez conscient des objectifs visés par Maven, de sa philosophie et des raisons pour lesquelles il devient un élément clé de la boîte à outils du développeur. Enfin, je souhaite réussir à vous transmettre mon enthousiasme pour ce projet libre, auquel vous pouvez participer en rejoignant le forum pour y exposer vos interrogations, apporter de nouvelles idées, proposer des contributions de toutes sortes et participer à l'amélioration générale de cet outil. Arnaud et moi avons commencé de cette façon avant de passer "de l'autre côté du miroir", mais au quotidien nous restons comme vous, avant tout, des utilisateurs de Maven, soucieux de disposer d'un outil pertinent et productif.

Nicolas de Loof

Image non disponible

Lorsque Nicolas m'a contacté pour écrire un ouvrage sur Maven en français, j'ai commencé par me demander si cela en valait la peine. Certes, la documentation du produit est critiquable. Elle est très dispersée, et il est souvent difficile de trouver l'information utile lorsqu'on ne sait pas où la chercher entre le site web du projet (1), ses nombreux plugins et son wiki (2). Pourtant, il existe désormais deux ouvrages en anglais disponibles gratuitement sur la Toile pour combler ces manques : Better Builds with Maven (3), publié en 2006, et Maven : The Definitive Guide (4), publié en 2007 et régulièrement mis à jour. Alors qu'apporter de plus qu'une simple traduction en français de ces ouvrages ?

Après de nombreuses années à utiliser et à préconiser Maven dans des contextes variés, j'avais envie de partager tout ce que j'avais pu emmagasiner comme bonnes pratiques et pointer sur les mauvaises que j'avais pu rencontrer. C'est sur ce principe que nous avons commencé avec Nicolas à bâtir le squelette de cet ouvrage. Fondé sur un projet fictif, il retrace nos expériences ainsi que celles des personnes que nous avions croisées sur notre chemin et permet d'expliquer les enjeux de Maven dans un projet et dans une entreprise. Même si nous n'avons pas recherché l'exhaustivité dans les cas traités, tellement ils peuvent être nombreux, nous avons essayé de faire apparaître les plus fréquents ou les plus épineux que nous ayons eus à résoudre. Nous avons axé nos efforts sur la présentation et la compréhension des concepts plutôt que sur le détail du paramétrage, lequel peut évoluer périodiquement.

J'espère que cet ouvrage saura autant vous divertir que vous former sur cet outil complet afin qu'il ne soit plus jamais complexe à vos yeux.

Arnaud Héritier

III-A. Contenu

Cet ouvrage se compose de quatre parties :

  • La première, du Chapitre 1 au Chapitre 5, aborde les concepts fondamentaux de Maven et leur mise en œuvre pratique. Nous avons choisi de mettre en scène de manière très explicite et souvent exagérée les problèmes que Maven tente de prendre en charge, afin que cette première partie soit aussi didactique que possible.

  • La deuxième, du Chapitre 6 au Chapitre 10, exploite des fonctionnalités plus avancées de Maven pour traiter des besoins orientés "gros projets d'entreprise" mais tout aussi délicats. Cette partie s'adresse typiquement aux développeurs intervenant sur des projets JavaEE (Java Enterprise Edition) en entreprise.

  • La troisième regroupe les Chapitres 11 à 15 et couvre des facettes plus spécialisées et moins mises en avant de Maven, mais que nous considérons comme tout aussi essentielles. Vous verrez alors que Maven ne se résume pas comme on le lit souvent à "un outil de compilation".

  • Pour terminer cet ouvrage le Chapitre 16 sera l'occasion de résumer les éléments clés présentés, de vous donner nos recommandations, bonnes et mauvaises pratiques à connaître pour tirer le meilleur de Maven. Par ailleurs, nous nous essayerons à l'exercice acrobatique de la boule de cristal en vous présentant l'avenir du projet Maven. Nous indiquerons comment aller au-delà de ce livre en participant à la communauté qui épaule ce projet open-source. Le Chapitre 17 conclura le récit de notre histoire et vous présentera les personnes qui nous ont inspiré les différents protagonistes.

Un dix-huitième chapitre vous propose un lexique qui éclaircit les mots quelques peu abscons utilisés dans cet ouvrage.

IV. Partie 1

Premiers pas avec Maven

IV-A. Chapitre 1 : Introduction

Commençons donc notre récit par l'inévitable mise en garde : toute ressemblance avec des personnes ou des situations existantes ou ayant existé ne serait que fortuite…

IV-A-1. Prologue

Image non disponible Image non disponible

Nicolas et Arnaud se sont rencontrés au cours d'une conférence organisée par un Java User Group (si vous ne participez pas à un JUG …​ et bien vous avez tort). Faisant connaissance autour d'un verre, ils évoquent les souvenirs de leurs premiers pas avec Java, devenu depuis leur plateforme de prédilection. Un Java Development Kit dans une version qui fait sourire aujourd'hui, et les bons vieux "Hello World" qui initient tout développeur à un nouveau langage. De nombreux souvenirs qui rappellent qu'on a tous débuté un jour, rencontré les mêmes problèmes et commis les mêmes erreurs idiotes que l'on dénonce aujourd'hui.

La première application un peu intéressante de Nicolas était un splendide outil de gestion de sa liste de courses. D'un naturel assez désorganisé, Nicolas n'a jamais réussi à mémoriser toute la liste. Il lui est même déjà arrivé de l'oublier ou pire, d'oublier tout simplement de faire les courses. Son application était donc un extraordinaire pense-bête, qu'il lançait à l'avance et qui lui envoyait fièrement, dix minutes avant son départ du bureau, un message de rappel avec la liste des courses. Autrement dit, un outil de rêve totalement indispensable, à tel point que le code de ce monument de l'informatique est respectueusement conservé quelque part.

Arnaud, confronté au même souci et amusé par cette solution de pur geek, lui demande s'il a toujours son programme et s'il peut en faire une copie pour satisfaire sa curiosité - la geekitude est dangereusement contagieuse !

IV-A-2. Partageons !

De retour à la maison, Nicolas fouille dans ses archives et en retire une vieille disquette (vous savez, ces carrés de plastique qu'on utilisait "dans le temps", avant que la clé USB et Internet ne les fassent disparaître). Il envoie donc le trésor tant convoité à Arnaud.

Pour vous faire une meilleure idée de cette exceptionnelle construction logicielle, voici les fichiers qui la constituent :

Image non disponible
Figure 01-01

La structure originale du projet "noubliepaslalistedescourses".

Arnaud, qui, semble-t-il, n'a vraiment que cela à faire de son temps libre, se jette sur cette magnifique relique des années Java 1.1 et tente de le compiler. Seulement, Arnaud est un utilisateur Mac. Le fichier BAT qui compile et assemble le logiciel en une archive Java JAR est inexploitable sur son système. Arnaud n'est pas du genre à se décourager si facilement, aussi écrit-il un fichier de compilation adapté à son environnement afin de pouvoir tester ce chef-d'œuvre de l'informatique.

Deux jours plus tard, profitant d'un peu de rangement, Nicolas retrouve une autre disquette contenant une version plus avancée de son logiciel, qui utilise les fonctions d'une bibliothèque utilitaire pour lire le fichier contenant la liste des courses. Il l'envoie donc à Arnaud, qui une nouvelle fois doit écrire son propre fichier de compilation.

Le "projet" étant trivial, la traduction du build.bat en build.sh est rapide. Voici pour comparaison les deux fichiers utilisés respectivement par Nicolas et Arnaud. Les différences sont minimes mais nécessitent une reprise manuelle à chaque modification, pouvant introduire des disparités, voire des incompatibilités entre les environnements de nos deux compères, qui peuvent leur faire perdre un temps précieux.

Listing 1.1 : Les fichiers de compilation utilisés respectivement par Nicolas et par Arnaud

Image non disponible
Image non disponible
 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
@echo off
set JAVA_HOME=C:\jdk1.3
set PATH=%JAVA_HOME%\bin
set CLASSPATH=lib\mail.jar;lib\activation.jar

mkdir build
javac -d build src\*.java
jar cf noubliepaslalistedescourses.jar build\*.class
 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
#!/bin/bash
export JAVA_HOME=/opt/jdk1.3
export PATH=$JAVA_HOME/bin
export CLASSPATH=lib/mail.jar:lib/activation.jar

mkdir build
javac -d build src/*.java
jar cf noubliepaslalistedescourses.jar build/*.class

De nombreux projets industriels ou communautaires sont confrontés à ce même problème et sont obligés de maintenir deux versions (ou plus) du script de construction du logiciel, soit parce que l'équipe n'est pas homogène, soit parce que l'environnement de test ou de production n'est pas équivalent à celui de développement. Même sur des systèmes d'exploitation identiques, les outils peuvent être installés à des emplacements différents, ce qui oblige à prévoir dans le script un ensemble de propriétés que chacun devra renseigner en fonction de sa configuration.

Sur Unix, ce problème a été traité depuis longtemps par l'outil make. Cependant, celui-ci n'est pas facilement exploitable sur les machines Windows, omniprésentes comme postes de développement.

Arnaud raconte ses déboires à son collègue Olivier. Ce dernier, utilisateur du système Solaris, s'est souvent trouvé face à ce problème ; il lui propose d'utiliser un fichier de commande universel, basé sur l'outil Apache Ant.

IV-A-3. Les fourmis à la rescousse

Qu'est-ce que c'est que ce "Ant" ? Faisons un détour par Wikipédia pour nous en faire une idée :

Ant (5) est un projet open-source de la fondation Apache, écrit en Java, qui vise le développement d'un logiciel d'automatisation des opérations répétitives tout au long du cycle de développement logiciel, à l'instar des logiciels Make.

Le nom est un acronyme pour Another Neat Tool (un autre chouette outil).

Ant est principalement utilisé pour automatiser la construction de projets en langage Java, mais il peut l'être pour tout autre type d'automatisation dans n'importe quel langage.

Parmi les tâches les plus courantes, citons la compilation, la génération de pages HTML de document (Javadoc), la génération de rapports, l'exécution d'outils annexes (checkstyle, findbugs, etc.), l'archivage sous forme distribuable (JAR, etc.).

Ant a connu un succès exceptionnel et occupe une place de choix dans la panoplie de tout développeur. Aucun logiciel dédié à Java ne peut aujourd'hui se permettre de ne pas fournir des tâches Ant. Le choix de cette solution semble donc la meilleure marche à suivre !

Image non disponible

Pour lui faciliter la tâche, Olivier envoie à Arnaud un script Ant, appelé avec beaucoup d'originalité build.xml, qu'il utilise lui-même sur la plupart de ses projets, et qui est donc rodé et bourré d'options et de paramètres indispensables permettant de le plier à tous les besoins courants.

Aurait-on trouvé avec Ant la solution miracle, rassemblant tous les suffrages ?

Image non disponible

Pas si simple : Nicolas, de son côté, désolé d'avoir causé tant de soucis à Arnaud, a reçu le même conseil de Fabrice, qui lui aussi a proposé un script de commandes Ant à tout faire, éprouvé par de nombreuses années d'utilisation. Le fichier d'Olivier suppose que les fichiers sources java sont stockés dans un répertoire sources et que les bibliothèques java sont placées sous libraries. Celui de Fabrice fait des choix différents, respectivement java et libs. De plus, la commande de compilation pour le fichier d'Olivier est ant package alors que celle de Fabrice est ant jar. La fusion de ces deux fichiers, chacun apportant des options intéressantes, est un véritable casse-tête. Rapidement, les quatre compères, qui commencent à se prendre au sérieux avec leur liste de courses, font appel à des connaissances spécialistes d'Ant pour les assister dans cette lourde tâche.

Ant a donc créé un nouveau métier dans le microcosme informatique : expert en script Ant ! Certains projets semblent jouer pour le concours du script le plus inutilement tordu, mixant des paramètres à n'en plus finir (que personne n'a d'ailleurs jamais eu besoin de modifier) et prenant en charge des cas de figure qui tiennent de l'expression artistique, le tout en important d'autres fichiers de script pour éviter l'ignoble copier-coller. S'ils sont fonctionnels, de tels scripts sont un enfer à maintenir et traduisent une organisation suspecte du projet, qui pourrait bien avoir laissé passer un élément de complexité inutile.

Pris au jeu, nos quatre amis - qui ont trouvé un boulot en or pour avoir autant de temps libre - ne s'avouent pas vaincus et veulent poursuivre ensemble le développement de ce projet. Des complications commencent à émerger. Notre petite équipe provenant d'horizons différents, chacun a ses habitudes "maison" et ses bonnes pratiques et voudrait les voir appliquées.

IV-A-4. Et Maven dans tout ça ?

Image non disponible

Au hasard d'un de ces appels au secours, Jason les prend à contre-pied et leur répond : "Et pourquoi ne pas utiliser plutôt Apache Maven ?" Surpris, et quelque peu incrédules devant cette proposition, ils mettent Jason au défi de compiler ce fameux logiciel avec son outil miracle, là où nos deux scripts Ant, pourtant irréprochables, pris séparément refusent obstinément la fusion. Et dix minutes plus tard, Jason envoie un fichier de quelques lignes, d'une simplicité surprenante, et les instructions de base pour installer Maven. À leur grande surprise, chacun arrive à compiler le projet sur son environnement, quelle que soit sa singularité.

Voici le fichier envoyé par Jason :

Listing 1.2 : pom.xml
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
<project>
  <modelVersion>4.0.0</modelVersion>
  <groupId>fr.noubliepaslalistedescourses</groupId>
  <artifactId>noubliepaslalistedescourses</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <build>
    <sourceDirectory>src</sourceDirectory>
  </build>
  <dependencies>
    <dependency>
      <groupId>javax.mail</groupId>
      <artifactId>mail</artifactId>
      <version>1.4</version>
    </dependency>
    <dependency>
      <groupId>commons-io</groupId>
      <artifactId>commons-io</artifactId>
      <version>1.4</version>
    </dependency>
  </dependencies>
</project>

Comparé aux fichiers Ant testés jusqu'ici, ce fichier "pom.xml" - quel drôle de nom - ne ressemble à rien de connu. Pas de directive de compilation, pas d'indication d'ordre dans les tâches, pas de commande d'assemblage du JAR. Où est le secret ?

IV-A-5. Que fait Maven ?

Épluchons point par point les consignes de Jason et voyons.

L'installation de Maven à proprement parler se résume à désarchiver un fichier ZIP et à définir la variable PATH pour y ajouter le chemin vers le répertoire apache-maven/bin. Il faut aussi s'assurer d'avoir la variable d'environnement JAVA_HOME qui indique l'emplacement du JDK (Java Development Kit), ce qui est généralement le cas sur le poste de travail des bons développeurs. La construction du projet s'effectue ensuite via la commande mvn package depuis la ligne de commande. Rien de bien révolutionnaire donc par rapport au script Ant que nous avions envisagé.

Jason nous a indiqué que Maven nécessitait une connexion à Internet. L'installation n'est donc pas complète, et Maven va rechercher sur le réseau les éléments manquants. Effectivement, la première exécution de Maven se traduit dans la console par une série de messages de téléchargements divers :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
D:\noubliepaslalistedescourses>mvn package
[INFO] Scanning for projects...
[INFO] ------------------------------------------------------------------------
[INFO] Building Unnamed - fr.noubliepaslalistedescourses:noubliepaslalistedescourses:jar:0.0.1-SNAPSHOT
[INFO]    task-segment: [package]
[INFO] ------------------------------------------------------------------------
Downloading: http://repo1.maven.org/maven2/org/apache/maven/plugins/maven-resources-plugin/2.2/maven-resources-plugin-2.2.pom
1K downloaded
Downloading: http://repo1.maven.org/maven2/org/apache/maven/plugins/maven-plugins/1/maven-plugins-1.pom
3K downloaded
Downloading: http://repo1.maven.org/maven2/org/apache/maven/maven-parent/1/maven-parent-1.pom
6K downloaded
Downloading: http://repo1.maven.org/maven2/org/apache/apache/1/apache-1.pom
3K downloaded
...

Cette liste de messages semble même interminable et avoir été conçue pour favoriser le développement d'Internet à haut débit. Tout ça pour notre projet composé de trois classes ? Jason nous a prévenus qu'à la première utilisation, Maven semble télécharger tout Internet, mais il nous a promis des explications ! Mise en garde quelque peu surprenante, mais laissons-lui le bénéfice du doute.

La mise en garde de Jason est judicieuse car de nombreux utilisateurs sont surpris par ce comportement de Maven et sa dépendance à une connexion Internet. Nous verrons par la suite ce qui impose ce mode de fonctionnement et en quoi cela sert les utilisateurs plutôt que de les contraindre.

Poursuivons l'analyse des messages que Maven trace dans la console, en ignorant les lignes liées à ces téléchargements étranges mais apparemment nécessaires :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
D:\noubliepaslalistedescourses>mvn package
[INFO] Scanning for projects...
[INFO] ------------------------------------------------------------------------
[INFO] Building Unnamed - fr.maven:noubliepaslalistedescourses:jar:0.0.1-SNAPSHOT
[INFO]    task-segment: [package]
[INFO] ------------------------------------------------------------------------
[INFO] [resources:resources]
[INFO] Using default encoding to copy filtered resources.
[INFO] [compiler:compile]
[INFO] Compiling 3 source files to D:\java\workspace\malistedecourses\target\classes
[INFO] [resources:testResources]
[INFO] Using default encoding to copy filtered resources.
[INFO] [compiler:testCompile]
[INFO] Nothing to compile - all classes are up to date
[INFO] [surefire:test]
[INFO] Surefire report directory: D:\java\workspace\malistedecourses\target\surefire-reports
-------------------------------------------------------
 T E S T S
-------------------------------------------------------
There are no tests to run.

Results :
Tests run: 0, Failures: 0, Errors: 0, Skipped: 0

[INFO] [jar:jar]
[INFO] Building jar:
D:\java\workspace\malistedecourses\target\malistedecourses-0.0.1-SNAPSHOT.jar
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 15 seconds
[INFO] Finished at: Fri Jan 02 17:02:09 CET 2009
[INFO] Final Memory: 6M/13M
[INFO] ------------------------------------------------------------------------

Nous constatons que Maven a compilé nos trois fichiers sources et construit un fichier JAR, ce qu'on attendait de lui, mais il a également tenté de copier des "ressources" et d'exécuter des tests, ensemble de traitements que nous n'avons spécifiés nulle part !

IV-A-6. La clé du mystère

Interrogé sur le sujet, Jason nous livre la clé du mystère : Ant, make et bon nombre d'outils similaires s'appuient sur une approche procédurale, pour laquelle on décrit les opérations à accomplir pour construire le logiciel ou exécuter des tâches annexes. Cela se traduit donc par une suite de commandes, qui prendra d'une façon ou d'une autre la forme décrite à la Figure 01-02.

Image non disponible
Figure 01-02

Les étapes élémentaires de construction d'un projet.

Cette approche fonctionne très bien et permet de faire à peu près tout ce qu'on veut, mais elle nécessite :

  • de répéter pour chaque nouveau projet une liste de tâches très similaires*, ce qui se traduit souvent par la copie d'un fichier de configuration considéré comme "faisant référence" ;

  • de gérer une liste de dépendances entre les étapes clés*, comme, dans notre exemple, "compiler" lorsqu'on désire assembler le JAR.

Maven choisit une approche différente, fondée sur le constat suivant : tous les projets Java vont suivre peu ou prou le même schéma. Les développeurs de Maven considèrent alors qu'il est plus simple de décrire en quoi un projet est différent de ce "scénario type" que de répéter invariablement des commandes très comparables d'un projet à l'autre. Maven exploite donc le concept très structurant de conventions.

IV-A-6-a. Convention plutôt que configuration

Notre pseudo-exemple réunissant les étapes "initialiser", "compiler", "assembler" semble s'appliquer à n'importe quel projet informatique, alors pourquoi devons-nous répéter cette déclaration pour chaque projet ? C'est exactement la question que soulève Maven et à laquelle il répond simplement : tout projet Java passe par une phase de préparation, de compilation puis d'assemblage. Ces trois phases ne sont pas propres à un projet, mais liées au développement informatique et s'appliquent à tous.

Maven définit donc un scénario type de construction d'un projet Java, avec des étapes clés prédéfinies et dont l'ordre est immuable. Ce "cycle de vie" est suffisamment large et consensuel pour être applicable à quasiment tous les projets. En admettant que le nôtre n'ait rien de particulier comparé à tous ceux que pilote Maven, nous comprenons mieux comment celui-ci a "deviné" les opérations nécessaires à sa construction.

Java Entreprise Edition suit également cette piste en proposant un environnement standardisé et un format de livraison commun pour les applications, même s'il existe de nombreux serveurs d'applications ayant des caractéristiques très variées. Construire une application web Java consiste à assembler une archive WAR (Web Application Archive), que l'on ait choisi JBoss, Webpshere, Tomcat ou Jetty pour l'exécuter. Le comportement "par convention" d'une application web est défini par une norme, chaque serveur proposant des options de configuration pour bénéficier d'un comportement personnalisé lorsque c'est nécessaire. Une convention a, bien sûr, un statut inférieur à une norme comme JavaEE, mais elle apporte la même simplification.

La force des conventions est d'offrir à ceux qui les suivent un outil directement exploitable, sans configuration complémentaire. Une convention de Maven concerne par exemple l'emplacement des fichiers sources Java à compiler. Notre fichier pom.xml contient effectivement une indication sourceDirectory que nous faisons pointer sur le répertoire src. Cette indication n'aurait pas été nécessaire si nous avions suivi la convention. Il nous suffit de l'adopter pour alléger d'autant notre configuration Maven.

Nous verrons en détail plus loin les diverses conventions préconisées par Maven. Certains trouveront cette structure inutilement complexe, peu pratique, ou au contraire parfaitement adaptée à leurs habitudes. L'essentiel n'est pas là, mais dans le fait que Maven propose une organisation par défaut, qui peut fonctionner sans plus d'indications pour tout projet qui la respecte. La force de Maven est de présenter une structure conventionnelle, qui évite à chacun un travail rébarbatif de configuration.

Maven reposant sur un scénario type de construction de projet Java, nous n'avons plus besoin d'indiquer la moindre commande. Il nous suffit de décrire en quoi notre projet est différent de ce cas stéréotypé. Nous passons d'une approche programmatique à une solution déclarative.

IV-A-6-b. Décrire plutôt que programmer

Notre fichier pom.xml de Maven ne compte aucune commande de compilation et, pourtant, il se traduit au final par l'exécution des outils de compilation et d'assemblage du JDK. Maven fait le choix d'une approche déclarative, dans laquelle on indique les particularités du projet et non la manière de le construire. On précise l'emplacement des fichiers sources, les bibliothèques qui sont nécessaires, plutôt que la ligne de commande du compilateur.

La différence est très significative, car il ne s'agit plus de définir les options de javac, mais de décrire une structure plus générale du projet, qui pourra être exploitée dans un autre contexte. Elle sera, par exemple, utilisée pour s'intégrer dans un IDE (Integrated Development Environment) comme Eclipse ou par les outils d'analyse de code.

IV-A-6-c. POM

Avec ces explications, revenons à présent sur le fichier pom.xml que Jason nous a écrit.

Tout d'abord, pourquoi ce nom ? Nous avons vu que ce fichier ne décrit pas la procédure de construction du projet mais qu'il rassemble des éléments descriptifs. Il est donc logique qu'il ne s'appelle pas build.xml (en dehors du conflit que cela introduirait avec les utilisateurs d'Ant).

Les trois lettres POM sont en fait l'acronyme de Project Object Model. Sa représentation XML est traduite par Maven en une structure de données riche qui représente le modèle du projet. Ces déclarations sont complétées avec l'ensemble des conventions qui viennent ainsi former un modèle complet du projet utilisé par Maven pour exécuter des traitements.

La première partie du POM permet d'identifier le projet lui-même.

Listing 1.5 : L'en-tête du fichier POM
Sélectionnez
1.
2.
3.
4.
    <modelVersion>4.0.0</modelVersion>
    <groupId>fr.noubliepaslalistedescourses</groupId>
    <artifactId>noubliepaslalistedescourses</artifactId>
    <version>0.0.1-SNAPSHOT</version>

L'élément modelVersion permet de savoir quelle version de la structure de données "modèle de projet" est représentée dans le fichier XML. « 4.0.0 » correspond à la version utilisée par Maven 2.x dans toutes ses variantes.

Image non disponible

Les futures versions de Maven 3 pourront exploiter des versions différentes de modèles et introduire des évolutions dans le format de ce fichier. Entre autre, sont envisagés :

  • l'import partiel d'autres fichiers POM (« mixins ») permettant de construire un projet par agrégation de bonnes pratiques,

  • des mécanismes avancés de gestion de dépendance,

  • et tout ce qui pourra s'avérer utile pour rendre Maven 3.x plus puissant et encore plus universel !

L'identifiant de groupe (groupId) permet de connaître l'organisation, l'entreprise, l'entité ou la communauté qui gère le projet. Par convention, on utilise le nom de domaine Internet inversé, selon la même logique que celle généralement recommandée pour les noms de package Java.

L'identifiant de composant (artifactId) est le nom unique du projet au sein du groupe qui le développe. En pratique et pour éviter des confusions, il est bon d'avoir un artifactId unique indépendamment de son groupId.

Enfin, on précise quelle version du projet est considérée. La plupart des projets utilisent la formule <Version Majeure>.<Version Mineure>.<Correctif>, même s'il est difficile d'obtenir un consensus sur la signification exacte de ces numéros et sur leur emploi. Vous pouvez utiliser une chaîne arbitraire, mais la syntaxe numérique permet de faire des comparaisons de versions et de trier celles-ci pour identifier automatiquement la plus récente. SNAPSHOT est un mot clé réservé de Maven, dont nous décrirons la fonction par la suite.

Le numéro de version est un concept délicat et changeant selon les organisations et la sensibilité de chacun. Nous vous recommandons une notation purement numérique qui facilite les comparaisons, selon la logique Majeur.Mineur.Correctif. Seules deux versions majeures peuvent ne pas assurer de compatibilité, une nouvelle version mineure peut apporter des fonctionnalités inédites mais s'interdit de ne pas respecter le mode de fonctionnement existant ; enfin, une version corrective n'apporte aucune fonctionnalité nouvelle mais élimine certains problèmes.

Certains enrichissent cette numérotation d'un dernier élément qui indique le degré de confiance dans une version donnée : "RC" pour une Release Candidate (version quasi finale), "GA" pour General Availability pour une version diffusée au public. Cet usage peut porter préjudice au projet car dans la comparaison purement alphabétique, "GA" est inférieur à "RC" !

La deuxième partie du POM concerne la construction du projet :

Listing 1.6 : Le bloc build du fichier POM
Sélectionnez
    <build>
        <sourceDirectory>src</sourceDirectory>
    </build>

L'approche déclarative utilisée par Maven permet de définir l'emplacement de nos fichiers sources. Le projet étant à la fois très simple et très banal, aucune autre déclaration n'est nécessaire. Si nous avions utilisé le répertoire conventionnel de Maven pour les fichiers sources Java, nous n'aurions même pas eu besoin de ce bloc <build> !

La troisième partie de POM concerne les bibliothèques dont dépend le projet :

Listing 1.7 : Le bloc dependencies du fichier POM
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
    <dependencies>
        <dependency>
            <groupId>javax.mail</groupId>
            <artifactId>mail</artifactId>
            <version>1.4</version>
        </dependency>
        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>1.4</version>
        </dependency>
    <dependencies>

Une nouvelle fois, l'approche déclarative prend le dessus : nous n'indiquons pas l'emplacement physique de ces bibliothèques, à savoir /lib pour notre projet, mais des identifiants groupId + artifactId
version. Il s'agit des mêmes identifiants de groupe, de composant et de version, que nous venons de rencontrer, appliqués à une bibliothèque. Nous indiquons, par exemple, que nous utilisons l'API standard JavaMail en version 1.4.

Nous avons ici une réponse partielle à notre question sur la nécessité d'un accès Internet : Maven va télécharger les bibliothèques indiquées, à partir d'une source fiable, plutôt que de se contenter des fichiers JAR présents dans le répertoire /lib et dont la version et l'origine sont incertaines. L'espace contenant l'ensemble des bibliothèques téléchargées est un dépôt d'archives local (local repository) et respecte une convention. Nous verrons en détail au Chapitre 2 les raisons de cette approche et ses avantages.

IV-A-6-d. Pourquoi adopter ces conventions ?

Nous venons de le voir, Maven propose un ensemble de conventions qui permettent d'outiller le projet avec peu de configuration. Il ne nous interdit cependant pas de choisir nos propres conventions, comme le répertoire src pour les sources du logiciel.

Dans ce cas, pourquoi adopter les conventions de Maven, alors qu'il suffit de quelques lignes de déclaration supplémentaires pour "plier" Maven à nos habitudes ? Hostiles au changement, comme une grande majorité des êtres humains, nous préférons cette option.

Image non disponible

C'est à ce moment qu'Emmanuel se propose de nous rejoindre, lui aussi à temps perdu grâce à son boulot en or, pour enrichir notre projet d'un grand nombre de nouvelles fonctionnalités. Emmanuel est déjà habitué à Maven et peut donc être rapidement productif et nous aider à le configurer correctement. Seulement, les choses ne se passent pas aussi simplement que prévu, car malgré son expérience de l'outil, Emmanuel ne retrouve pas ses petits : pour ajouter des tests à notre architecture, il doit créer un nouveau répertoire de sources, indépendant de celles du projet. Or notre répertoire src n'a qu'un seul niveau et ne permet pas de différencier le livrable des tests. Il est donc obligé de déclarer une nouvelle dérogation aux conventions de Maven.

Par ailleurs, même si les différences sont minimes, il est contraint d'adapter toutes ses petites habitudes à notre structure de répertoire, qui n'est pas "strictement conforme Maven".

Les conventions de Maven ne sont pas obligatoires, cependant réfléchissez à deux fois avant de vouloir en imposer d'autres pour votre projet. D'une part, vous allez vous compliquer inutilement la tâche en ne profitant pas du comportement par défaut que propose Maven, et chaque nouvelle option activée pourra se traduire par une nouvelle phase de configuration. À moins d'être passionnés par l'éditeur XML, peu de développeurs prennent du plaisir à perdre un temps précieux dans des fichiers de configuration, Maven ou autres.

Ensuite, pensez à la gestion de vos équipes et à l'intégration de nouveaux développeurs. Maven offre l'occasion de définir une fois pour toutes la structure de tous vos projets Java, de manière homogène. Un développeur pourra passer d'un projet à un autre sans perdre son temps à apprendre les petites habitudes locales : où sont les fichiers de configuration ? Dans quel répertoire place-t-on les données de test ? Tous les projets qui se conforment aux conventions Maven seront identiques de ce point de vue, et le développeur sera plus rapidement productif.

Enfin, contrairement à une politique "maison" qui aurait pu établir ce type de conventions, celles de Maven sont partagées par la majorité des développeurs qui ont adopté ce logiciel. Tout nouveau membre de votre équipe qui a déjà travaillé sur un projet Maven trouvera rapidement ses repères. Maven et ses conventions deviennent au fil des années le standard de facto dans le monde professionnel Java car un développeur trouve immédiatement ses marques lorsqu'il aborde un nouveau projet.

La force des conventions de Maven n'est pas dans le nom des répertoires qui ont été choisis, mais dans le fait qu'il offre à la communauté des développeurs Java tout entière une base commune.

IV-A-7. La force de Maven

Revenons un peu en arrière : le projet initial, que nous pouvons considérer comme un prototype, était difficilement exportable en dehors de l'environnement de son créateur. Il nécessitait un script de compilation à la fois indispensable et sans grande valeur ajoutée, étant d'une grande banalité.

L'adoption d'Ant aurait pu partiellement résoudre le problème, mais pour tirer parti de la richesse des outils qui peuvent lui être greffés, il aurait fallu que tous les scripts Ant adoptent une structure de base commune. En l'absence d'une convention dans la communauté Ant pour les éléments principaux qui gouvernent un projet Java, il peut être extrêmement délicat de réutiliser et de fusionner des éléments provenant de sources indépendantes. Enfin, tout ce travail aurait été réalisé par des copier-coller qu'il aurait fallu répéter pour notre prochain projet.

Maven propose de passer à une approche déclarative, dans laquelle nous considérerons notre projet comme une variation sur un thème commun. Nous ne nous soucions plus de savoir quelle opération doit suivre quelle autre lors de la construction du logiciel. Nous déclarons juste les quelques éléments spécifiques qui font de notre projet quelque chose d'unique.

En adoptant des conventions, nous réduisons à quelques lignes les informations que nous devons déclarer pour que le projet soit pris en charge par Maven. La maintenance et l'ajout de nouvelles tâches au cours de la construction du projet s'en trouvent simplifiés. Un développeur, issu d'un contexte très différent mais déjà utilisateur de l'outil, peut prendre le projet en main sans difficulté particulière.

La combinaison de conventions et d'une approche innovante fondée sur la description du projet fait de Maven un outil à part, très différent d'Ant ou de ses équivalents. Au cours des chapitres qui suivent, nous allons voir en quoi cette approche se généralise à toutes les tâches qui accompagnent la vie d'un projet.

Vous avez aimé ce tutoriel ? Alors partagez-le en cliquant sur les boutons suivants : Viadeo Twitter Facebook Share on Google+   


Petit rappel de vos lointains cours de physique : S est le symbole utilisé en physique pour l'entropie :)
Sonatype, Inc. (http://www.sonatype.com)

  

Copyright © 2018 . Aucune reproduction, même partielle, ne peut être faite de ce site ni de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.