Escolar Documentos
Profissional Documentos
Cultura Documentos
Apache
Nicolas De loof et Arnaud Hritier
Prface de Jason Van Zyl
Rseaux
et tlcom
Programmation
Gnie logiciel
Scurit
Systme
dexploitation
Apache Maven
Nicolas De loof
et Arnaud Hritier
Pearson Education France a apport le plus grand soin la ralisation de ce livre afin de vous fournir une information complte et fiable. Cependant, Pearson Education France nassume de responsabilits, ni pour son utilisation, ni pour les contrefaons de brevets ou atteintes aux droits de tierces
personnes qui pourraient rsulter de cette utilisation.
Les exemples ou les programmes prsents dans cet ouvrage sont fournis pour illustrer les descriptions
thoriques. Ils ne sont en aucun cas destins une utilisation commerciale ou professionnelle.
Pearson Education France ne pourra en aucun cas tre tenu pour responsable des prjudices
ou dommages de quelque nature que ce soit pouvant rsulter de lutilisation de ces exemples ou
programmes.
Tous les noms de produits ou marques cits dans ce livre sont des marques dposes par leurs
propritaires respectifs.
Apache, Apache Maven, Maven, and the Apache Maven logo are trademarks of The Apache
Software Foundation. Used with permission. No endorsement by The Apache Software Foundation
is implied by the use of these marks.
Aucune reprsentation ou reproduction, mme partielle, autre que celles prvues larticle L. 122-5 2 et 3 a) du code de la
proprit intellectuelle ne peut tre faite sans lautorisation expresse de Pearson Education France ou, le cas chant, sans
le respect des modalits prvues larticle L. 122-10 dudit code.
All rights reserved. No part of this book may be reproduced or transmitted in any form or by any means, electronic or
mechanical, including photocopying, recording or by any information storage retrieval system, without permission from
Pearson Education, Inc.
XI
Prface ................................................................................................................................
XIII
Partie I
Premiers pas avec Maven
1 Introduction ..................................................................................................................
Prologue ......................................................................................................................
Partageons ! ................................................................................................................
Les fourmis la rescousse ..........................................................................................
Et Maven dans tout a ? ..............................................................................................
Que fait Maven ? ........................................................................................................
La cl du mystre ........................................................................................................
Convention plutt que configuration .....................................................................
Dcrire plutt que programmer .............................................................................
POM ......................................................................................................................
Pourquoi adopter ces conventions ? ......................................................................
La force de Maven ......................................................................................................
3
3
4
6
7
8
10
11
12
12
15
16
17
17
17
20
21
22
23
26
27
IV
Apache Maven
27
30
32
33
33
35
36
38
39
40
41
42
45
45
48
50
52
53
55
55
56
58
60
61
62
65
65
67
68
69
70
71
73
73
74
75
76
78
79
82
84
85
86
Partie II
Maven en entreprise
6 Gestion avance des dpendances ...............................................................................
Oracle, quand tu nous tiens ........................................................................................
Un moteur de recherche pour Maven ....................................................................
Pourquoi publier un POM sans JAR ? ......................................................................
Installer le fichier manquant .................................................................................
Les dpendances "System" ...................................................................................
Crer son propre dpt ...............................................................................................
Contrle didentit, vos papiers sil vous plat ! ...................................................
Rebelote : mais o est javax.jms ? ........................................................................
Grer son dpt priv .................................................................................................
Mtadonnes ...............................................................................................................
Passer un "vritable" gestionnaire de dpt .............................................................
Un miroir de central .............................................................................................
Un gestionnaire dartefacts ...................................................................................
Conclusion ..................................................................................................................
91
91
92
93
94
94
96
96
97
98
100
100
101
101
106
107
107
108
109
110
111
111
112
114
115
115
116
117
117
VI
Apache Maven
119
119
120
123
126
128
128
132
134
134
135
135
137
137
139
141
141
142
143
143
143
144
145
147
148
149
149
149
150
152
152
153
153
153
154
154
154
155
156
VII
157
157
157
158
158
159
160
160
161
163
163
163
165
166
168
Partie 3
Encore plus loin avec Maven
11 Utiliser un outil non support....................................................................................
Un outil maison ..........................................................................................................
Rutiliser lexistant ...............................................................................................
Retour dans un monde de scripts ? .......................................................................
Crer un plugin ...........................................................................................................
Pas de panique ! ....................................................................................................
Des paramtres pour le plugin ..............................................................................
Un modle dynamique ..........................................................................................
Plexus ....................................................................................................................
Des classes et des royaumes .............................................................................
Au-del de Java .....................................................................................................
Tester notre plugin ......................................................................................................
Plugin testing harness ...........................................................................................
Plugin invoker .....................................................................................................
Conclusion ..................................................................................................................
171
171
172
174
174
174
176
177
178
180
183
185
186
187
189
12 Lassurance qualit.....................................................................................................
Audit de code ..............................................................................................................
Analyse statique ....................................................................................................
Analyse dynamique ...............................................................................................
191
191
192
195
VIII
Apache Maven
198
200
201
202
202
203
204
207
209
209
210
211
212
214
216
217
219
220
221
222
223
223
224
224
225
226
226
228
228
229
230
230
231
232
233
235
236
236
237
IX
Le support .............................................................................................................
Le cot de Maven ..................................................................................................
La concurrence ...........................................................................................................
Maven bon partout ? .............................................................................................
Ant et Ivy ...............................................................................................................
EasyAnt..................................................................................................................
Gradle.....................................................................................................................
Maven 1 .................................................................................................................
Buildr .....................................................................................................................
Un outil reconnu .........................................................................................................
La communaut .....................................................................................................
Lquipe de dveloppement ..................................................................................
Ladoption en entreprise .......................................................................................
Lavenir de Maven ......................................................................................................
Maven 2.x .............................................................................................................
Maven 3.x .............................................................................................................
qui appartient Maven ? ...........................................................................................
La fondation Apache ............................................................................................
Sonatype ................................................................................................................
Maven + OSGi = Tycho ........................................................................................
Non, Sonatype nest pas seul ! ..............................................................................
La garantie par lopen-source ...............................................................................
Conclusion ..................................................................................................................
238
240
240
240
242
242
242
244
244
244
245
247
247
248
249
251
255
256
256
257
258
259
260
261
261
262
262
264
265
266
267
268
268
269
269
271
Apache Maven
17 pilogue .......................................................................................................................
Rcapitulons ...............................................................................................................
Sortez de lamateurisme .............................................................................................
Le mot de la fin ...........................................................................................................
Qui est qui ? ................................................................................................................
Les membres francophones de lquipe Maven ....................................................
Les membres de la communaut Java ...................................................................
Post-scriptum ........................................................................................................
273
274
274
275
275
275
281
283
18 Lexique ........................................................................................................................
Le petit monde open-source .......................................................................................
Les concepts Maven ...................................................................................................
Ceux qui font tourner Maven ......................................................................................
Et tout ce qui tourne autour ....................................................................................
Liens utiles ..................................................................................................................
285
285
287
291
293
294
Index ...................................................................................................................................
295
Listing 1.4 : Seconde excution de Maven sans tlchargement cette fois ....................
13
14
14
30
51
57
58
59
Listing 4.4 : Accs aux fichiers de test en tant que ressources ...........................................
61
Listing 4.5 : Construction dun test-jar en mme temps que larchive java du projet ..
66
67
75
77
78
Listing 5.4 : Prparation dune base de donnes de test "propre" avec le plugin SQL ......
80
83
91
109
113
124
125
129
XII
Apache Maven
130
Listing 8.5 : Configuration du plugin Surefire pour excuter nos tests Selenium ..............
131
132
137
173
175
176
182
183
184
Listing 11.7 : Test unitaire pour un plugin, bas sur le plugin-testing-harness ......
186
187
188
188
199
205
210
211
213
215
217
219
220
225
Listing 14.2 : Gnration dun nouveau projet partir dun archtype .............................
226
227
243
Listing 15.2 : Un POM Maven 3 bas sur les attributs XML .............................................
254
Listing 16.1 : Un profil pour viter les plugins trop consommateurs sous m2eclipse .......
270
Listing 16.2 : Un profil pour activer le cycles de vie reconfigurable de m2eclise 0.9.9 ....
271
Prface
Histoire de Maven
Maven est n au sein du projet Jakarta Alexandria. Ce projet, aujourd'hui
arrt, ft le terreau non seulement de Maven mais aussi d'autres projets
comme Gump et Forrest. Le premier import des sources du prototype eu
lieu en aot 2001. Maven vcu pendant environ 5 mois au sein d'Alexandria avant de
rejoindre sa nouvelle adresse dans le projet Turbine.
Bien que Maven ft ses dbuts dans Alexandria, le test en grandeur nature fut le projet
Turbine. Turbine tentait de dcoupler ses couches persistance, service, et prsentation
web dans des builds spars et j'tais exaspr de devoir grer de multiples scripts de
compilation trs semblables. Il n'y avait pas de moyen simple cette poque pour crer
des modles de scripts Ant, chaque build semblait diffrent. Je trouvais cela incroyablement frustrant et futile : personne n'tait intress de savoir comment la construction
s'effectuait tant qu'elle fonctionnait et qu'elle tait facile utiliser. L'infrastructure d'un
projet est incroyablement importante, mais sa valeur rside dans l'application dveloppe. En consquence le build est souvent nglig et tend vous lcher quand vous en
avez le plus besoin, par exemple lors de la prparation d'une livraison ou lorsque
plusieurs personnes interviennent sur le projet. Dans le projet Jakarta, il y a plusieurs
annes, il tait rare qu'un build Ant fonctionne tel quel.
Les dveloppeurs de Turbine ont souffert lorsque j'ai essay de faire fonctionner
Maven, ce que je regrette, mais j'imagine mal comment un nouveau projet peut dmarrer et survivre si personne ne souffre. Je pensais que c'tait pour leur propre bien (je suis
connu pour avoir une opinion ou deux sur le sujet) et, aprs quelques grincements de
dents, Maven est arriv maturit. Cela me rappelle une de mes citations favorite de
Ralph Johsnon et Don Roberts dans Patterns for Evolving Frameworks :
Les gens crent de l'abstraction en gnralisant des exemples concrets. Toute tentative de dfinir l'abstraction correcte sur papier sans dvelopper et excuter un
systme rel est condamne l'chec. Personne n'est aussi dou. Un framework est
une conception rutilisable, donc il se construit en regardant les choses dont il est
sens tre le modle. Plus vous avez d'exemples sous la main, plus le framework
pourra tre gnrique.
XIV
Apache Maven
Je ne savais pas vraiment quoi le rsultat final ressemblerait, mais je savais qu'il devait
y avoir une meilleure faon de faire. Pour commencer, je savais ce que je voulais :
m
un modle pour le projet, pour qu'il n'y ait qu'un seul endroit o aller chercher
l'information relative au projet ;
une structure standardise pour qu'il ne soit pas ncessaire d'aller la pche aux
bibliothques, au code source et la documentation.
La chose suivante que je notais tait que tous les JAR dont nous dpendions taient
stocks sous CVS. Nous perdions de la place en conservant plusieurs copies de bibliothques comme Xerces. chaque fois qu'une nouvelle version de Xerces apparaissait,
je devais mettre jour chaque projet. Mais plus grave, sans gestion dclarative il n'y
avait aucun moyen d'effectuer une analyse. Les gens ont tendance sous-estimer
l'importance d'une gestion dclarative. Ils se disent que c'est si simple de placer les
bibliothques dans le gestionnaire de sources, mais essayez de dcomposer votre gros
projet poubelle en composants rutilisables et maintenables, ou d'analyser ce qui sera
ncessaire l'excution entre toutes vos applications avec des dpendances communes
dans la chane et vous serrez bien ennuy. La vraie puissance de la gestion dclarative ne tient pas l'conomie de quelques octets de disque (quoique cela puisse tre
significatif si on n'y prend pas garde) mais la possibilit d'analyse. Une fois un
graphe de dpendances en place, tout devient possible. Mais retour l'histoire :
maintenant que la gestion dclarative des dpendances existait, il fallait rendre plus
simple le partage des librairies. Juste aprs avoir cr Maven nous avons cr le rfrentiel Maven, un rfrentiel de librairies qui est utilis aujourd'hui par la plupart des
dveloppements Java.
Beaucoup de personnes ont eu des soucis avec Maven 1, mais il fonctionnait gnralement bien, et tous les outils dans leur premire gnration souffrent de divers dfauts.
La seule faon d'aller au del est d'en prendre de la graine et de crer quelque chose de
mieux pour le coup d'aprs. Nous avons cr Maven 2.0, et aprs plusieurs annes nous
sommes sur le point de publier Maven 3.0. Avec tous les retours que les dveloppeurs
ont reu de la part de l'incroyable communaut des utilisateurs de Maven, je pense que
nous sommes arrivs quelque chose de solide sur lequel nous pouvons itrer. Ne vous
inquitez pas : Maven 3.0 est 100 % compatible avec l'existant en Maven 2.0 :-) Nous
avons dsormais une comprhension trs complte sur comment les organisations construisent leurs applications, depuis le dveloppement en passant par les tests et jusqu' la
mise en production. Ce sont toutes ces connaissances qui ont t utilises pour crer les
bases de Maven 3.0.
Prface
XV
propos de ce livre
Nicolas et Arnaud ont choisi, avec une approche lgre et rcrative, de proposer un
guide aux utilisateurs novices, bas sur l'histoire d'une start-up technologique qui fait le
choix d'utiliser Maven. Le livre couvre toutes les phases du projet, de son origine
jusqu' l'tape finale de livraison et de dploiement d'un produit complet. Les lecteurs
dcouvrent progressivement les bonnes pratiques de Maven travers les utilisations que
nos experts en font et bnficient de techniques puissantes qu'il faudrait sans cela des
mois pour apprendre.
Le livre Apache Maven n'est pas seulement une introduction pratique Maven, mais
c'est aussi un guide o chaque leon est base sur un exemple. Je pense qu'Arnaud et
Nicolas ont ralis un super travail, demandant beaucoup d'efforts. Je recommande sans
hsitation cet ouvrage toute personne s'intressant Maven : c'est un ouvrage de rfrence et de grande valeur pour la communaut Maven.
Jason Van Zyl,
Fondateur du projet Apache Maven
Avant-propos
Lcriture dun ouvrage technique nest pas une tche triviale, car il est
facile de perdre le lecteur dans une avalanche de concepts thoriques ou
de sgarer dans des dtails non fondamentaux. Dcrire un outil comme
Maven, ou tout simplement le dfinir clairement, tout en restant accessible tous, est encore plus dlicat : soit on reste trop vague, et le lecteur na plus qu
attendre le Chapitre 5 pour commencer apprendre quelque chose de concret, soit on
sembarque dans de longues explications de principes et de concepts et le lecteur
nattendra jamais ce mme Chapitre 5.
Pour tre honnte, je dois dire que les premires bauches de cet ouvrage sont immanquablement tombes dans ces travers, ce qui annonait un livre bien peu pertinent pour
les utilisateurs, quils soient novices ou dj expriments. Lorsque jai soumis les
premiers jets de ce projet Arnaud, il men a rapidement fait la remarque et nous nous
sommes accords sur la forme que nous voulions donner ce livre.
Mon objectif est de communiquer ma passion autour de ce projet open-source quest
Maven, lequel runit des dveloppeurs aux parcours trs diffrents. Les rencontres que
jai faites dans cette communaut ont forg mon approche de linformatique. Avec cette
motivation, tablir un dictionnaire impersonnel Maven-Franais tait exclu ; aussi jai
rapidement choisi, en accord avec Arnaud, de privilgier une approche aussi didactique
que possible, btie sur des exemples concrets issus de ma propre exprience du terrain.
Il est difficile de sensibiliser les utilisateurs aux enjeux que Maven tente de grer, alors
quils y sont pourtant confronts en permanence. Situation intressante o tout le
monde rencontre un problme, mais, faute de mettre un nom dessus et den valuer
limportance, celui-ci reste latent tout au long de la vie du projet, amenant parfois des
situations critiques. Nous allons suivre ensemble la vie dun projet fictif, bien que largement inspir de situations relles. Il passera par toutes les phases, du prototype crit sur
un coin de table lapplication stratgique dentreprise de grande envergure, ce qui
nous permettra de couvrir un trs large ventail de situations.
Plutt que de dcrire le rle de Maven sur un projet, ou de vous accabler par un long
expos thorique sur ses concepts, je prfre au travers de cette dmonstration un peu
romance vous montrer les difficults concrtes auxquelles Maven sattaque. Sur la
base de ces exemples, parfois volontairement excessifs, je souhaite vous dmontrer de
manire ludique les avantages que Maven peut apporter vos projets. Malgr les caricatures proposes, de nombreuses situations vous sembleront familires. Derrire la
fiction se cachent des cas bien rels, que je nai fait quamplifier, et beaucoup auront des
points communs avec vos propres difficults. Ce parallle vous donnera une image
raliste de Maven et des conseils applicables dans les meilleurs dlais.
Jespre que vous apprcierez ce choix et que vous tirerez un enseignement pratique du
texte qui suit. En particulier, jaimerais quarriv au bout de votre lecture vous soyez
conscient des objectifs viss par Maven, de sa philosophie et des raisons pour lesquelles
il devient un lment cl de la bote outils du dveloppeur. Enfin, je souhaite russir
vous transmettre mon enthousiasme pour ce projet libre, auquel vous pouvez participer
en rejoignant le forum pour y exposer vos interrogations, apporter de nouvelles ides,
proposer des contributions de toutes sortes et participer lamlioration gnrale de cet
outil. Arnaud et moi avons commenc de cette faon avant de passer "de lautre ct du
miroir", mais au quotidien nous restons comme vous, avant tout, des utilisateurs de
Maven, soucieux de disposer dun outil pertinent et productif.
Nicolas De loof
Lorsque Nicolas ma contact pour crire un ouvrage sur Maven en franais, jai commenc par me demander si cela en valait la peine. Certes, la
documentation du produit est critiquable. Elle est trs disperse, et il est
souvent difficile de trouver linformation utile lorsquon ne sait pas o la
chercher entre le site web du projet1, ses nombreux plugins et son wiki2. Pourtant, il
existe dsormais deux ouvrages en anglais disponibles gratuitement sur la Toile pour
combler ces manques : Better Builds with Maven3, publi en 2006, et Maven : The Definitive Guide4, publi en 2007 et rgulirement mis jour. Alors quapporter de plus
quune simple traduction en franais de ces ouvrages ?
Aprs de nombreuses annes utiliser et prconiser Maven dans des contextes varis,
javais envie de partager tout ce que javais pu emmagasiner comme bonnes pratiques et
pointer sur les mauvaises que javais pu rencontrer. Cest sur ce principe que nous
avons commenc avec Nicolas btir le squelette de cet ouvrage. Fond sur un projet
1.
2.
3.
4.
http://maven.apache.org.
http://docs.codehaus.org/display/MAVENUSER.
MaestroDev (http://www.maestrodev.com).
Sonatype, Inc. (http://www.sonatype.com).
Avant-propos
XIX
fictif, il retrace nos expriences ainsi que celles des personnes que nous avions croises
sur notre chemin et permet dexpliquer les enjeux de Maven dans un projet et dans une
entreprise. Mme si nous navons pas recherch lexhaustivit dans les cas traits, tellement ils peuvent tre nombreux, nous avons essay de faire apparatre les plus frquents
ou les plus pineux que nous ayons eus rsoudre. Nous avons ax nos efforts sur la
prsentation et la comprhension des concepts plutt que sur le dtail du paramtrage,
lequel peut voluer priodiquement.
Jespre que cet ouvrage saura autant vous divertir que vous former sur cet outil complet
afin quil ne soit plus jamais complexe vos yeux.
Arnaud Hritier
Contenu
Cet ouvrage se compose de quatre parties :
m
La deuxime, du Chapitre 6 au Chapitre 10, exploite des fonctionnalits plus avances de Maven pour traiter des besoins orients "gros projets dentreprise" mais tout
aussi dlicats. Cette partie sadresse typiquement aux dveloppeurs intervenant sur
des projets JEE (Java Enterprise Edition) en entreprise.
Pour terminer cet ouvrage le Chapitre 16 sera loccasion de rsumer les lments
cls prsents, de vous donner nos recommandations, bonnes et mauvaises pratiques connatre pour tirer le meilleur de Maven. Par ailleurs, nous nous essayerons
lexercice acrobatique de la boule de cristal en vous prsentant lavenir 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 rcit de
notre histoire et vous prsentera les personnes qui nous ont inspir les diffrents
protagonistes.
Un dix-huitime chapitre vous propose un lexique qui claircit les mots quelques peu
abscons utiliss dans cet ouvrage.
Partie I
Premiers pas avec Maven
1
Introduction
Commenons donc notre rcit par linvitable mise en garde : toute ressemblance avec
des personnes ou des situations existantes ou ayant exist ne serait que fortuite
Prologue
Nicolas et Arnaud se sont rencontrs au cours dune confrence organise par un Java User Group. Faisant connaissance autour dun verre, ils voquent les souvenirs de leurs
premiers pas avec Java, devenu depuis leur plateforme de prdilection. Un Java Development Kit dans une version qui fait sourire aujourdhui, et les bons vieux "Hello World"
qui initient tout dveloppeur un nouveau langage. De nombreux souvenirs qui rappellent quon a tous dbut un jour, rencontr les mmes problmes et commis les mmes
erreurs idiotes que lon dnonce aujourdhui.
La premire application un peu intressante de Nicolas tait un splendide outil de
gestion de sa liste de courses. Dun naturel assez dsorganis, Nicolas na jamais russi
mmoriser toute la liste. Il lui est mme dj arriv de loublier ou pire, doublier tout
simplement de faire les courses. Son application tait donc un extraordinaire pensebte, quil lanait lavance et qui lui envoyait firement, dix minutes avant son dpart
du bureau, un message de rappel avec la liste des courses. Autrement dit, un outil de
rve totalement indispensable, tel point que le code de ce monument de linformatique
est respectueusement conserv quelque part.
Partie I
Arnaud, confront au mme souci et amus par cette solution de pur geek, lui demande
sil a toujours son programme et sil peut en faire une copie pour satisfaire sa curiosit
la geekitude est dangereusement contagieuse !
Partageons !
De retour la maison, Nicolas fouille dans ses archives et en retire une vieille disquette
(vous savez, ces carrs de plastique quon utilisait "dans le temps", avant que la cl
USB et Internet ne les fassent disparatre). Il envoie donc le trsor tant convoit
Arnaud.
Pour vous faire une meilleure ide de cette exceptionnelle construction logicielle, voici
les fichiers qui la constituent :
Figure 1.1
La structure originale du projet "noubliepaslalistedescourses".
Arnaud, qui, semble-t-il, na vraiment que cela faire de son temps libre, se jette sur
cette magnifique relique des annes 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 systme. Arnaud nest pas du genre se dcourager si
facilement, aussi crit-il un fichier de compilation adapt son environnement afin de
pouvoir tester ce chef-duvre de linformatique.
Deux jours plus tard, profitant dun peu de rangement, Nicolas retrouve une autre
disquette contenant une version plus avance de son logiciel, qui utilise les fonctions
Chapitre 1
Introduction
dune bibliothque utilitaire pour lire le fichier contenant la liste des courses. Il lenvoie
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 utiliss respectivement par Nicolas et Arnaud. Les diffrences sont minimes mais ncessitent une reprise manuelle chaque modification,
pouvant introduire des disparits, voire des incompatibilits entre les environnements
de nos deux compres, qui peuvent leur faire perdre un temps prcieux.
Listing 1.1 : Les fichiers de compilation utiliss respectivement par Nicolas et par Arnaud
@echo off
set JAVA_HOME=C:\jdk1.3
set PATH=%JAVA_HOME%\bin
set CLASSPATH=lib\mail.jar;lib\
activation.jar
#!/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
mkdir build
javac -d build src/*.java
jar cf noubliepaslalistedescourses.jar
build/*.class
Partie I
Ant a connu un succs exceptionnel et occupe une place de choix dans la panoplie de
tout dveloppeur. Aucun logiciel ddi Java ne peut aujourdhui se permettre de ne
pas fournir des tches Ant. Le choix de cette solution semble donc la meilleure marche
suivre !
Pour lui faciliter la tche, Olivier envoie Arnaud un script Ant, appel avec
beaucoup doriginalit build.xml, quil utilise lui-mme sur la plupart de
ses projets, et qui est donc rod et bourr doptions et de paramtres indispensables permettant de le plier tous les besoins courants.
Aurait-on trouv avec Ant la solution miracle, rassemblant tous les suffrages ?
Pas si simple : Nicolas, de son ct, dsol davoir caus tant de soucis
Arnaud, a reu le mme conseil de Fabrice, qui lui aussi a propos un script
de commandes Ant tout faire, prouv par de nombreuses annes dutilisation. Le fichier dOlivier suppose que les fichiers sources java sont stocks dans un
rpertoire sources et que les bibliothques java sont places sous libraries. Celui de
Fabrice fait des choix diffrents, respectivement java et libs. De plus, la commande de
compilation pour le fichier dOlivier est ant package alors que celle de Fabrice est ant
jar. La fusion de ces deux fichiers, chacun apportant des options intressantes, est un
vritable casse-tte. Rapidement, les quatre compres, qui commencent se prendre au
srieux avec leur liste de courses, font appel des connaissances spcialistes dAnt
pour les assister dans cette lourde tche.
1. Source : http://fr.wikipedia.org/wiki/Apache_Ant.
Chapitre 1
Introduction
Partie I
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>1.4</version>
</dependency>
</dependencies>
</project>
Compar aux fichiers Ant tests jusquici, ce fichier "pom.xml" quel drle de nom
ne ressemble rien de connu. Pas de directive de compilation, pas dindication dordre
dans les tches, pas de commande dassemblage du JAR. O est le secret ?
task-segment: [package]
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
Chapitre 1
Introduction
Downloading: http://repo1.maven.org/maven2/org/apache/maven/maven-parent/1/mavenparent-1.pom
6K downloaded
Downloading: http://repo1.maven.org/maven2/org/apache/apache/1/apache-1.pom
3K downloaded
...
Cette liste de messages semble mme interminable et avoir t conue pour favoriser le
dveloppement dInternet haut dbit. Tout a pour notre projet compos de trois
classes ? Jason nous a prvenus qu la premire utilisation, Maven semble tlcharger
tout Internet, mais il nous a promis des explications ! Mise en garde quelque peu
surprenante, mais laissons-lui le bnfice du doute.
INFO
La mise en garde de Jason est judicieuse car de nombreux utilisateurs sont surpris par ce
comportement de Maven et sa dpendance une connexion Internet. Nous verrons par la
suite ce qui impose ce mode de fonctionnement et en quoi cela sert les utilisateurs plutt
que de les contraindre.
Poursuivons lanalyse des messages que Maven trace dans la console, en ignorant les
lignes lies ces tlchargements tranges mais apparemment ncessaires :
Listing 1.4 : Seconde excution de Maven sans tlchargement cette fois
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.
10
Partie I
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 quon attendait de lui, mais il a galement tent de copier des
"ressources" et dexcuter des tests, ensemble de traitements que nous navons
spcifis nulle part !
La cl du mystre
Interrog sur le sujet, Jason nous livre la cl du mystre : Ant, make et bon nombre
doutils similaires sappuient sur une approche procdurale, pour laquelle on dcrit les
oprations accomplir pour construire le logiciel ou excuter des tches annexes. Cela
se traduit donc par une suite de commandes, qui prendra dune faon ou dune autre la
forme dcrite la Figure 1.2.
tape
Traitement
Initialiser
Ncessite
Compiler
Ncessite
Assembler
Figure 1.2
Les tapes lmentaires de construction dun projet.
Chapitre 1
Introduction
11
Cette approche fonctionne trs bien et permet de faire peu prs tout ce quon veut,
mais elle ncessite :
m
de rpter pour chaque nouveau projet une liste de tches trs similaires, ce qui
se traduit souvent par la copie dun fichier de configuration considr comme
"faisant rfrence" ;
de grer une liste de dpendances entre les tapes cls, comme, dans notre exemple,
"compiler" lorsquon dsire assembler le JAR.
Maven choisit une approche diffrente, fonde sur le constat suivant : tous les projets
Java vont suivre peu ou prou le mme schma. Les dveloppeurs de Maven considrent
alors quil est plus simple de dcrire en quoi un projet est diffrent de ce "scnario type"
que de rpter invariablement des commandes trs comparables dun projet lautre.
Maven exploite donc le concept trs structurant de conventions.
Convention plutt que configuration
Notre pseudo-exemple runissant les tapes "initialiser", "compiler", "assembler"
semble sappliquer nimporte quel projet informatique, alors pourquoi devons-nous
rpter cette dclaration pour chaque projet ? Cest exactement la question que soulve
Maven et laquelle il rpond simplement : tout projet Java passe par une phase de
prparation, de compilation puis dassemblage. Ces trois phases ne sont pas propres
un projet, mais lies au dveloppement informatique et sappliquent tous.
Maven dfinit donc un scnario type de construction dun projet Java, avec des tapes
cls prdfinies et dont lordre est immuable. Ce "cycle de vie" est suffisamment large
et consensuel pour tre applicable quasiment tous les projets. En admettant que le
ntre nait rien de particulier compar tous ceux que pilote Maven, nous comprenons
mieux comment celui-ci a "devin" les oprations ncessaires sa construction.
Java Entreprise Edition suit galement cette piste en proposant un environnement standardis et un format de livraison commun pour les applications, mme sil existe de
nombreux serveurs dapplications ayant des caractristiques trs varies. Construire
une application web Java consiste assembler une archive WAR (Web Application
Archive), que lon ait choisi JBoss, Webpshere, Tomcat ou Jetty pour lexcuter. Le
comportement "par convention" dune application web est dfini par une norme, chaque
serveur proposant des options de configuration pour bnficier dun comportement
personnalis lorsque cest ncessaire. Une convention a, bien sr, un statut infrieur
une norme comme JEE, mais elle apporte la mme simplification.
La force des conventions est doffrir ceux qui les suivent un outil directement exploitable, sans configuration complmentaire. Une convention de Maven concerne par
exemple lemplacement des fichiers sources Java compiler. Notre fichier pom.xml
12
Partie I
contient effectivement une indication sourceDirectory que nous faisons pointer sur le
rpertoire src. Cette indication naurait pas t ncessaire si nous avions suivi la
convention. Il nous suffit de ladopter pour allger dautant notre configuration Maven.
Nous verrons en dtail plus loin les diverses conventions prconises par Maven.
Certains trouveront cette structure inutilement complexe, peu pratique, ou au contraire
parfaitement adapte leurs habitudes. Lessentiel nest pas l, mais dans le fait que
Maven propose une organisation par dfaut, qui peut fonctionner sans plus dindications pour tout projet qui la respecte. La force de Maven est de prsenter une structure
conventionnelle, qui vite chacun un travail rbarbatif de configuration.
Maven reposant sur un scnario type de construction de projet Java, nous navons plus
besoin dindiquer la moindre commande. Il nous suffit de dcrire en quoi notre projet
est diffrent de ce cas strotyp. Nous passons dune approche programmatique une
solution dclarative.
Dcrire plutt que programmer
Notre fichier pom.xml de Maven ne compte aucune commande de compilation et, pourtant, il se traduit au final par lexcution des outils de compilation et dassemblage du
JDK. Maven fait le choix dune approche dclarative, dans laquelle on indique les particularits du projet et non la manire de le construire. On prcise lemplacement des
fichiers sources, les bibliothques qui sont ncessaires, plutt que la ligne de commande
du compilateur.
La diffrence est trs significative, car il ne sagit plus de dfinir les options de javac,
mais de dcrire une structure plus gnrale du projet, qui pourra tre exploite dans un
autre contexte. Elle sera, par exemple, utilise pour sintgrer dans un IDE (Integrated
Development Environment) comme Eclipse ou par les outils danalyse de code.
POM
Avec ces explications, revenons prsent sur le fichier pom.xml que Jason nous a crit.
Tout dabord, pourquoi ce nom ? Nous avons vu que ce fichier ne dcrit pas la procdure de construction du projet mais quil rassemble des lments descriptifs. Il est donc
logique quil ne sappelle pas build.xml (en dehors du conflit que cela introduirait avec
les utilisateurs dAnt).
Les trois lettres POM sont en fait lacronyme de Project Object Model. Sa reprsentation XML est traduite par Maven en une structure de donnes riche qui reprsente le
modle du projet. Ces dclarations sont compltes avec lensemble des conventions
qui viennent ainsi former un modle complet du projet utilis par Maven pour excuter
des traitements.
Chapitre 1
Introduction
13
14
Partie I
Une nouvelle fois, lapproche dclarative prend le dessus : nous nindiquons pas
lemplacement physique de ces bibliothques, savoir /lib pour notre projet, mais des
identifiants groupId + artifactId + version. Il sagit des mmes identifiants de
groupe, de composant et de version, que nous venons de rencontrer, appliqus une
bibliothque. Nous indiquons, par exemple, que nous utilisons lAPI standard JavaMail
en version 1.4.
Nous avons ici une rponse partielle notre question sur la ncessit dun accs Internet : Maven va tlcharger les bibliothques indiques, partir dune source fiable,
plutt que de se contenter des fichiers JAR prsents dans le rpertoire /lib et dont la
version et lorigine sont incertaines. Lespace contenant lensemble des bibliothques tlcharges est un dpt darchives local (local repository) et respecte une
convention. Nous verrons en dtail au Chapitre 2 les raisons de cette approche et ses
avantages.
Chapitre 1
Introduction
15
16
Partie I
Enfin, contrairement une politique "maison" qui aurait pu tablir ce type de conventions, celles de Maven sont partages par la majorit des dveloppeurs qui ont adopt ce
logiciel. Tout nouveau membre de votre quipe qui a dj travaill sur un projet Maven
trouvera rapidement ses repres. Maven et ses conventions deviennent au fil des annes
le standard de facto dans le monde professionnel Java car un dveloppeur trouve immdiatement ses marques lorsquil aborde un nouveau projet.
La force des conventions de Maven nest pas dans le nom des rpertoires qui ont t
choisis, mais dans le fait quil offre la communaut des dveloppeurs Java tout entire
une base commune.
La force de Maven
Revenons un peu en arrire : le projet initial, que nous pouvons considrer comme un
prototype, tait difficilement exportable en dehors de lenvironnement de son crateur.
Il ncessitait un script de compilation la fois indispensable et sans grande valeur ajoute,
tant dune grande banalit.
Ladoption dAnt aurait pu partiellement rsoudre le problme, mais pour tirer parti de
la richesse des outils qui peuvent lui tre greffs, il aurait fallu que tous les scripts Ant
adoptent une structure de base commune. En labsence dune convention dans la
communaut Ant pour les lments principaux qui gouvernent un projet Java, il peut
tre extrmement dlicat de rutiliser et de fusionner des lments provenant de sources
indpendantes. Enfin, tout ce travail aurait t ralis par des copier-coller quil aurait
fallu rpter pour notre prochain projet.
Maven propose de passer une approche dclarative, dans laquelle nous considrerons
notre projet comme une variation sur un thme commun. Nous ne nous soucions plus
de savoir quelle opration doit suivre quelle autre lors de la construction du logiciel.
Nous dclarons juste les quelques lments spcifiques qui font de notre projet quelque
chose dunique.
En adoptant des conventions, nous rduisons quelques lignes les informations que
nous devons dclarer pour que le projet soit pris en charge par Maven. La maintenance
et lajout de nouvelles tches au cours de la construction du projet sen trouvent simplifis. Un dveloppeur, issu dun contexte trs diffrent mais dj utilisateur de loutil,
peut prendre le projet en main sans difficult particulire.
La combinaison de conventions et dune approche innovante fonde sur la description
du projet fait de Maven un outil part, trs diffrent dAnt ou de ses quivalents. Au
cours des chapitres qui suivent, nous allons voir en quoi cette approche se gnralise
toutes les tches qui accompagnent la vie dun projet.
2
Au-del de java.lang
Des JAR sous CVS
Avec une quipe qui se compose dsormais de cinq dveloppeurs motivs, il nest plus
question de senvoyer par e-mail des archives du projet pour transmettre aux autres les
nouvelles fonctions que lon vient de dvelopper. Un projet en mode collaboratif utilise
un outil de gestion de sources pour partager le code, synchroniser les dveloppements
et grer les conflits lorsque deux personnes travaillent sur le mme fichier. Ce gestionnaire de sources (SCM Source Control Management) est typiquement CVS (Concurrent
Version System), Subversion ou, plus rcemment, Git.
Comme son nom lindique, cet outil est prvu pour contenir des fichiers sources et non
des binaires issus dune compilation. Pourtant, de nombreux projets placent les bibliothques et les outils ncessaires au projet dans leur gestionnaire de sources. Lide peut
sembler bonne a priori, car elle vise grer avec un unique outil et, de manire homogne, tous les lments ncessaires au dveloppement du projet. Sauvegarder les bibliothques Java dans le SCM est donc une garantie de retrouver tout moment la version
exacte qui est utilise par le projet.
Notre prototype ne droge pas cette "bonne ide" et possde comme tant dautres un
rpertoire lib avec lensemble des bibliothques utilises.
Quand le rpertoire lib explose
La croissance de lquipe nous permet de rapidement amliorer notre prototype. Le
nombre de bibliothques ncessaires au projet augmente. Nous commenons par introduire Spring pour rendre le code plus volutif avec lutilisation des concepts de linjection de dpendances. Ensuite, nous remplaons tout le code crit en JDBC par
Hibernate et Java Persistence API. Nous dveloppons une interface web sympathique
18
Partie I
base sur Wicket et, enfin, nous faisons appel Apache CXF pour exposer nos services
dautres applications sous forme de services web.
Le nombre de bibliothques croit exponentiellement car, au-del de la gestion de celles
que nous utilisons explicitement au sein du projet, il faut grer toutes les bibliothques
qui leur sont ncessaires. Rapidement, le rpertoire lib se retrouve charg de dizaines
de fichiers JAR avec des noms plus ou moins htroclites.
Les choses se compliquent alors significativement et la moindre mise jour dune
bibliothque relve dun casse-tte chinois.
Dune part, cette pratique encourage utiliser ces bibliothques telles quelles, sans
chercher sassurer de leur origine ou de la fiabilit de leur tlchargement. Comme il
est dlicat de comparer deux versions dun fichier binaire, il nous est impossible de
savoir en quoi notre fichier util.jar diffre de celui utilis sur un autre projet comparable, dont nous voulons importer des classes intressantes. Mme si ces deux fichiers
portent le mme nom et ont la mme taille, cela ne signifie pas quils soient identiques.
Seule une comparaison binaire pourrait nous en assurer.
Autant dire quavec les dizaines de bibliothques embarques dans notre projet, plus
personne ne fait scrupuleusement cette vrification et nous nous contentons de lire le
nom de larchive mail-1.2.jar pour identifier la bibliothque JavaMail.
Cela nous amne un second problme possible. Supposons que cette bibliothque ait
t corrompue lors de son tlchargement depuis le site de SUN qui la diffuse ou de son
enregistrement dans notre SCM. Un transfert rseau nest jamais 100 % garanti, et un
seul bit modifi peut rendre la bibliothque inutilisable, sans parler de ces charmants
petits virus qui peuvent traner un peu partout. Lidentification du problme peut tre
extrmement complexe, car la remise en cause de la bibliothque sera probablement la
toute dernire hypothse que nous voquerons pour justifier un dysfonctionnement.
Un bogue est dtect
Aprs quelques heures de tests et de recherche dinformations sur Internet, nous devons
nous rendre lvidence, nous rencontrons un bogue connu de la bibliothque JavaMail
utilise sur le projet. Seule solution viable : la mise jour de cette bibliothque dans
une version plus rcente.
Chapitre 2
Au-del de java.lang
19
En supposant que nous sachions rpondre sans ambigut cette question, nous devons
supprimer le mail-1.2.jar utilis jusquici et ajouter le nouveau mail-1.4.1.jar.
Cela nous impose de modifier tous nos scripts de gestion du projet (scripts de compilation et de lancement, fichiers de configuration Eclipse, NetBeans ou IntelliJ Idea)
pour tenir compte de ce changement, avec le risque dintroduire, par mgarde, des
erreurs. Ce simple changement nous oblige donc la fois faire preuve de beaucoup de
soin et vrifier le fonctionnement de nos scripts.
Pour viter ces risques, une seconde option consiste ne pas indiquer de numro de
version pour les bibliothques. Nous utilisons le nom de fichier mail.jar et le remplaons purement et simplement par le nouveau fichier en cas de mise jour. Ayons alors
une pense compatissante pour les quipes de maintenance qui, dans quelques annes,
devront deviner la version exacte des bibliothques utilises sur notre projet, dont
certaines seront devenues plus ou moins obsoltes et connues pour certains bogues
graves. Le problme devient encore plus complexe lorsquon doit utiliser une version
modifie dune bibliothque, par exemple parce quon y a intgr un correctif qui nest
pas encore pris en compte dans une version officielle.
INFO
Le format darchive JAR prvoit un fichier de mtadonnes, META-INF/MANIFEST.MF, dcrivant thoriquement la bibliothque, et en particulier sa version prcise. Celle-ci est cependant rgulirement non documente lorsque ce fichier MANIFEST nest pas tout simplement
absent ou quasiment vide.
lib/*.jar
Pour ne plus rencontrer ce problme, nous dcidons "dassouplir" nos scripts de compilation en utilisant lintgralit du rpertoire lib comme chemin daccs aux classes,
plutt quune liste explicite de bibliothques. Placer une nouvelle bibliothque dans ce
rpertoire ou en remplacer une par une autre version ne ncessitera alors aucune modification des scripts.
Ce qui pourrait ressembler la solution miracle nest pas aussi parfait quil y parat.
Dune part, cela ne rsout pas la configuration de notre environnement de dveloppement qui continue de rclamer une liste prcise de bibliothques inclure dans le
ClassPath. Ensuite, une manipulation malheureuse de nos fichiers JAR ne se verra pas
20
Partie I
Il ny a ici aucune quivoque possible. Toute autre variante de JavaMail possdera dans
le dpt Maven un numro de version diffrent. Si nous devions nous-mmes appliquer
un correctif, nous devrions utiliser un numro de version adquat, comme 1.4-patch1234. Dans ce cas, cette bibliothque modifie serait place dans notre dpt priv,
comme nous le verrons au Chapitre 6.
Notre projet inclut galement une mystrieuse bibliothque util.jar. Nicolas ne se
souvient pas du tout de lorigine de ce fichier. Les quipes de maintenance, confrontes
ce cas de figure, auraient du fil retordre. Comment grer une mise niveau ou un
bogue rencontr dans la bibliothque considre si on est incapable de lidentifier avec
prcision ?
Dans le contenu de cette archive java, les packages utiliss, org.apache.commons.io,
nous mettent sur la piste, et cest ce qui a inspir Jason la dclaration dune dpendance vers Apache Commons-io. Cependant, il pourrait sagir dune version modifie,
pour une quelconque raison, avec je ne sais quel impact possible sur lapplication.
Chapitre 2
Au-del de java.lang
21
Lidentification exacte rclame par Maven oblige prciser quelle version est utilise
et dfinir des numros de version pour chaque variante de la bibliothque ou version
modifie que lon voudrait utiliser.
Ajouter une bibliothque un projet Maven se traduit simplement par lajout dun bloc
<dependency> comparable notre exemple, identifiant sans quivoque notre intention.
Pas de script diter, pas de fichier JAR tlcharger et donc pas de validation du fichier
tlcharg ; pas de rpertoire de bibliothques modifier, avec les risques derreur de
synchronisation qui en dcouleraient. Mettre jour une bibliothque consiste tout
simplement modifier linformation de version qui lui est associe.
ASTUCE
Les bibliothques standard de Java sont hberges par SUN et devraient donc tre places
sous le groupe com.sun.java. Elles ne peuvent cependant pas tre considres comme des
fournitures appartenant cet diteur. Aussi, la convention pour ce cas particulier veut quon
utilise le nom de package javax.* qui caractrise ces API. Par ailleurs, il existe de nombreuses
exceptions pour des raisons historiques lies la premire mouture de Maven.
Dpt de bibliothques
La configuration par dfaut de Maven utilise le dpt (ou rfrentiel) de bibliothques
http://repo1.maven.org/maven2/. Ce site, maintenu par la communaut Maven,
compte plusieurs dizaines de gigaoctets de bibliothques libres de diffusion et est mis
jour plusieurs fois par jour. Nous verrons au fil des prochains chapitres comment utiliser
dautres dpts et en construire un pour ses besoins propres.
partir de notre dclaration de dpendance, Maven va construire lURL du sousrpertoire ddi la bibliothque indique :
<URL du dpt> / <groupId en tant que chemin> / <artifactId> / <version>
Un fichier porte le mme nom que la bibliothque avec le suffixe -sources. Il sagit,
comme on pourrait sen douter, dune archive des sources Java de la bibliothque,
22
Partie I
Figure 2.1
Le sous-rpertoire ddi JavaMail 1.4 sur le dpt de bibliothques.
Un autre fichier ayant le mme nom que la bibliothque avec lextension .pom.
Il sagit bien de lacronyme du Project Object Model que nous connaissons dj.
Chaque bibliothque dans le dpt Maven possde un fichier de ce type. Soit parce
que la bibliothque a t dveloppe en utilisant Maven, soit parce quun fichier
minimal a t crit pour fournir une description de la bibliothque aux utilisateurs
de Maven.
Chapitre 2
Au-del de java.lang
23
Lorsquon fait appel une bibliothque pour prendre en charge certaines fonctions
techniques, il est rare quelle se suffise elle-mme. Au mme titre que notre projet,
elle fait appel dautres bibliothques spcialises pour lui fournir des composants de
haut niveau qui lui facilitent la tche. Sa documentation prcise, bien videmment, ces
prrequis, ce qui nous a permis lors de son introduction dans le projet de connatre la
liste de bibliothques ajouter pour avoir un ensemble fonctionnel. Certaines taient
dj intgres, et il a fallu nous assurer que la version demande tait compatible avec
celle que nous utilisions et, ventuellement, faire la mise jour qui simposait.
Les bibliothques de haut niveau, telles que le framework Spring, introduisent dans le
projet un nombre important de bibliothques. Les choses se compliquent lorsquon
dsire changer de version pour profiter de nouvelles fonctionnalits ou dun correctif.
Nous devons retracer la main la chane complte des bibliothques pour identifier ce
qui a chang, en nous fondant sur la documentation respective de chaque bibliothque
rencontre pour connatre ses prrequis et ses ventuelles incompatibilits.
Pour nous pargner une migraine, les dveloppeurs de bibliothques ont heureusement
pris la bonne habitude de ne jamais briser la compatibilit avec les versions prcdentes
sans un avertissement visible. La pratique la plus courante consiste utiliser le numro
de version et passer une version "majeure" suprieure. Entre la version 1.4 et la
version 2.0, il est assez probable que des modifications lourdes ont t apportes, limitant fortement la compatibilit, ce qui justifie le changement de version. Par contre,
nous pouvons tre plus confiants dans une migration vers une 1.4.2 ou une 1.5, et relcher (dans la limite du raisonnable) notre surveillance pour passer dune 1.4.2 une
1.4.3.
Malgr cette pratique courante, la gestion de la chane de dpendances entre bibliothques peut devenir rellement complexe, si on ne veut oublier personne en route.
Labsence dune bibliothque peut provoquer des erreurs non videntes et qui napparatront pas ncessairement au premier dmarrage de lapplication. Quant lire attentivement la documentation de chaque bibliothque, aucun dveloppeur ne trouve le
courage de le faire systmatiquement.
La plupart du temps, on se contente donc de prendre la distribution binaire de la bibliothque et de fusionner son rpertoire lib avec celui du projet, en tentant didentifier les
doublons. Mme si cela fonctionne relativement bien dans de nombreux cas, il est
certain quon part au petit bonheur la chance en esprant ne rien laisser traner en route.
Lami de mon ami
Que propose Maven pour cette situation ? Nous avons vu quil demande de dclarer les
dpendances plutt que de fournir nous-mmes les binaires ; aussi, notre dernire
24
Partie I
option prendre la distribution telle quelle et la fusionner avec notre rpertoire lib
nest pas applicable. Maven va-t-il nous obliger plucher la documentation de chaque
bibliothque utilise ?
Maven est autrement plus subtil : jetez un coup dil quelques pages en arrire, sur le
contenu du rpertoire lib de notre projet initial :
\lib
\mail.jar
\activation.jar
\util.jar
Nous utilisons trois bibliothques, la premire est lAPI JavaMail, la deuxime le Bean
Activation Framework, ncessaire au bon fonctionnement de JavaMail, et enfin le
mystrieux util.jar qui sest avr tre Apache commons-io. Le fichier POM.xml ne
compte que deux entres <dependency>, l o notre projet ncessite trois bibliothques.
Jason aurait-il t un peu trop vite ?
Si vous jetez nouveau un il aux traces de tlchargement dont Maven nous a abreuvs au premier lancement, vous constaterez quil tlcharge la fois des fichiers POM et
des fichiers JAR comme sil ne tlchargeait pas dj assez de choses !
Ces fichiers POM, au mme titre que celui de notre projet, dcrivent les bibliothques
auxquelles ils sont associs. Pour JavaMail, larchive mail-1.4.jar est ainsi accompagne dun mail-1.4.pom. Il sagit bien dun fichier Project Object Model, au mme
format XML que pour notre projet et qui comprend des dclarations comparables, en
particulier des dpendances. Cest ici quest indiqu le lien entre JavaMail et le Bean
Activation Framework. Cela permet Maven de savoir que tout projet qui utilisera
lAPI JavaMail aura ncessairement besoin du JAR activation. Si celui-ci a aussi des
dpendances, la chane se poursuivra, jusqu ce quun graphe complet de bibliothques
interdpendantes soit construit.
On parle pour ces donnes qui dcrivent la bibliothque de "mtadonnes". Il sagit
dune version compacte et normalise au format POM des informations que nous
aurions pu obtenir en lisant la documentation de la bibliothque : sa licence, le site web
qui lhberge, et ses prrequis. Lexploitation automatise de ces donnes permet
Maven de construire larbre des dpendances du projet, chaque nouvelle feuille
pouvant, par ses propres mtadonnes, introduire de nouvelles branches.
Cet arbre, extrmement difficile construire la main et douloureux maintenir, est
analys automatiquement par Maven chaque excution. Il sassure que lensemble des
bibliothques ncessaires est prsent et construit ainsi le chemin de classes utilis par le
compilateur. Maven va galement grer les problmes de conflit de version, lorsque
larbre fait apparatre plusieurs fois la mme bibliothque dans des versions diffrentes.
Chapitre 2
Au-del de java.lang
25
Noubliepaslalistedescourses
Version : 3.4.0.GA
Version : 2.5.6
Dpendances du projet
Spring-context
Hibernate-entitymanager
Dpendances de la dpendance
Dpendances de la dpendance
Spring-core
Version : 3.3.1.GA
Hibernate-core
Version : 1.0.4
Version : 1.1
Commons-logging
Conflit de version
Figure 2.2
Arbre de dpendances transitives.
Le mcanisme utilis est cependant limit par la libert laisse aux numros de version
qui rend dlicat une comparaison 100 % dterministe.
INFO
Lalgorithme de rsolution des conflits se fonde sur le principe de "proximit" : Maven
compte, dans larbre des dpendances, combien de branches sparent la bibliothque du
projet. Celle qui est dclare au plus prs gagne, et, en cas dgalit, la plus rcente
lemporte sur la base dune comparaison des numros de version. Les versions futures
de Maven intgreront un mcanisme configurable de dpendance, qui permettra de
choisir une politique de gestion de conflit, par exemple pour faire face des numros de
version exotiques pour lesquels Maven est incapable deffectuer correctement une
comparaison.
Cette dernire fonctionnalit finit par nous convaincre dfinitivement. Aussi, nous abandonnons nos diffrents scripts et adoptons les conventions de Maven pour la suite du
dveloppement de noubliepaslalistedescourses. Les dveloppeurs sont nombreux
choisir Maven pour sa gestion des dpendances. Noubliez pas, cependant, tous les
points que nous avons dj vus, et en quoi cela diffrencie Maven dautres outils de
construction de projet. Maven nest pas juste un outil de gestion des dpendances, pour
26
Partie I
lesquelles il existe dautres trs bons outils comme Apache Ivy qui sont utilisables
depuis un script Ant.
Ayez bien en tte les points forts et la philosophie de Maven, si vous envisagez de
convertir un projet existant, car vous devrez probablement en repenser lorganisation, et
pas juste crire quelques fichiers POM pour dclarer vos dpendances.
Testons un peu
Vincent est un fanatique de la qualit logicielle, aussi a-t-il fait un gros
travail dvanglisation pour nous convaincre doutiller notre projet de tests
automatiss (nous en reparlerons au Chapitre 4). Ceux-ci permettent de
contrler tout moment que les fonctionnalits de notre projet ne sont pas impactes
par une modification, ce qui constitue une scurit et un gain de temps apprciables.
Nous tions sur le point de dcerner Vincent le prix trs convoit de "dveloppeur du
mois", quand nous avons rencontr un bogue trange sur lapplication, signalant
labsence de la classe org.junit.Assert dans lenvironnement dexcution. Voil un
problme bien curieux.
Aprs une rapide recherche, nous constatons quune erreur dimport dans une classe a
fait utiliser org.junit.Assert#assertNotNull() la place de la classe similaire de
Spring org.springframework.util.Assert#notNull(). La gestion automatique des
imports par notre environnement de dveloppement intgr est bien pratique mais
elle peut parfois avoir des effets pervers 2. Comment se fait-il que cette erreur
dtourderie soit passe au travers des mailles de notre (excellent) suivi qualit ? Ou
plutt, comment se fait-il que notre outillage qualit ait pu ajouter des bogues
notre application ?
La rponse tient en un mot : dpendances. Notre gestion des dpendances la hussarde,
avec un rpertoire lib dont nous utilisons tous les JAR sans distinction, ne sait pas diffrencier les bibliothques ncessaires la compilation de celles utilises par les outils de
test.
Nous pourrions fiabiliser les choses en sparant nos bibliothques en /lib/runtime et
/lib/test, mais Jason nous arrte net : que penser des API servlet, que nous utilisons
pour compiler notre interface de gestion web (lapplication a pas mal volu depuis le
prototype en ligne de commande !). Ces bibliothques sont ncessaires pour compiler
mais elles ne doivent pas tre intgres lapplication pour respecter les rgles JEE, car
elles sont dj prsentes dans notre serveur dapplication.
2. Ne riez pas, il sagit dun cas bien rel, identifi lors de la migration du projet sous Maven !
Chapitre 2
Au-del de java.lang
27
28
Partie I
Maven construit pour nous larchive web WAR de lapplication que nous pouvons
dployer sur notre serveur de test.
Un coup dil au rpertoire WEB-INF/lib de lapplication web nous fait cependant
dchanter : plus de quarante bibliothques sy trouvent (qui a demand tout a ?). Il y a,
par exemple, la bibliothque avalon, un framework ancien que plus personne nutilise.
Plus grave, nous trouvons dans ce rpertoire des bibliothques redondantes, comme un
commons-logging-1.0.4 et un commons-logging-api-1.1. Voil qui est bien troublant.
Maven se serait-il emml les pinceaux dans ses dpendances ?
La rponse nos interrogations est cependant simple : Maven nest pas un magicien et
il ne peut grer les dpendances entre bibliothques que grce aux mtadonnes quil
extrait des fichiers POM de chacune. La qualit de ces informations est dterminante
pour obtenir une gestion fine et sans accrocs des dpendances. Il arrive malheureusement quune bibliothque dclare des dpendances qui ne sont pas indispensables son
fonctionnement, ou bien propose plusieurs variantes. Dans ce cas, Maven a bien du mal
sy retrouver.
La bibliothque commons-logging en est une bonne illustration. Il sagit dune bibliothque qui sert de faade pour passer de manire transparente dun outil de log un
autre, par exemple de log4j au mcanisme intgr dans java partir de la version 1.4,
ou encore logkit, un autre outil comparable.
Le fichier POM de commons-logging dclare donc des dpendances vers toutes les
bibliothques de log quil supporte. La dclaration Maven correcte devrait tre :
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.12</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>logkit</groupId>
<artifactId>logkit</artifactId>
<version>1.0.1</version>
<optional>true</optional>
</dependency>
...
Chapitre 2
Au-del de java.lang
29
INFO
La qualit des mtadonnes a longtemps t un point faible de Maven, qui se corrige
heureusement avec le temps et les nouvelles versions des bibliothques incrimines. Les
projets, mme ceux qui nutilisent pas Maven pour leurs propres besoins, sont aujourdhui
sensibiliss ce besoin et prennent plus de soin dfinir des dpendances fiables.
Pour les versions anciennes cependant, une mise jour nest pas possible, car la politique de
lquipe qui gre le dpt de bibliothques de rfrence est de ne jamais modifier un POM
qui a t publi, en raison du grand nombre de miroirs et de caches utiliss par la communaut : un fichier modifi signifierait quun miroir pourrait ne pas fournir la mme version
que le dpt de rfrence, ce qui pourrait introduire des bogues insurmontables dans les
projets. Sans compter que chaque utilisateur devrait manuellement purger son dpt local
pour forcer Maven rcuprer la version corrige !
Maven possde heureusement une solution de contournement. Lorsque nous dfinissons une dpendance, nous pouvons exclure certains lments de la transitivit. Ainsi,
si nous voulons empcher Spring qui utilise commons-logging dintroduire sur
notre projet ce fameux JAR avalon-framework, nous pouvons crire :
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>2.5.6</version>
<exclusions>
<exclusion>
<groupId>avalon-framework</groupId>
<artifactId>avalon-framework</artifactId>
</exclusion>
</exclusions>
</dependency>
30
Partie I
+- org.apache.geronimo.specs:geronimo-jaxws_2.1_spec:jar:1.0:compile
[INFO] |
+- org.apache.geronimo.specs:geronimo-ws-metadata_2.0_spec:jar:1.1.2:compile
[INFO] |
+- asm:asm:jar:2.2.3:compile
[INFO] |
+- org.apache.cxf:cxf-rt-bindings-xml:jar:2.1.4:compile
[INFO] |
+- org.apache.cxf:cxf-rt-frontend-simple:jar:2.1.4:compile
[INFO] |
+- org.apache.cxf:cxf-rt-ws-addr:jar:2.1.4:compile
[INFO] |
+- javax.xml.soap:saaj-api:jar:1.3:compile
[INFO] |
\- com.sun.xml.messaging.saaj:saaj-impl:jar:1.3.2:compile
Chapitre 2
[INFO]
[INFO]
[INFO]
[INFO]
[INFO]
[INFO]
[INFO]
...
|
|
|
+|
+|
Au-del de java.lang
31
\- javax.xml.ws:jaxws-api:jar:2.1:compile
+- javax.annotation:jsr250-api:jar:1.0:compile
\- javax.jws:jsr181-api:jar:1.0-MR1:compile
org.springframework:spring-aspects:jar:2.5.6:compile
\- org.aspectj:aspectjweaver:jar:1.6.2:compile
org.hibernate:hibernate-annotations:jar:3.4.0.GA:compile
\- org.hibernate:ejb3-persistence:jar:1.0.2.GA:compile
Lanalyse de cet arbre permet didentifier les bibliothques qui font appel commonslogging-api et dexclure cet intrus de notre projet.
Ces commandes bien pratiques restent assez spartiates, cantonnes dans la console.
Lintgration de Maven dans les environnements de dveloppement en offre une
version nettement plus ergonomique. La Figure 2.3 prsente le plugin Maven pour
Eclipse (m2eclipse) et sa fentre danalyse des dpendances. Si on slectionne une
dpendance dans la zone de droite, il nous indique tous les chemins de dpendance qui
y mnent. Un simple clic permet de placer les exclusions qui simposent sans diter
manuellement le fichier POM.
Figure 2.3
Plugin Maven pour Eclipse.
32
Partie I
Conclusion
La gestion des bibliothques et de leurs dpendances est une fonctionnalit de Maven
trs rgulirement mise en avant. Manuellement, cette gestion peut en effet devenir un
rel casse-tte, et la rponse apporte par Maven est la fois lgante et volutive. Sur
de gros projets, nous avons vu que celle-ci peut cependant draper et introduire involontairement des bibliothques inutiles ou redondantes mais, heureusement, Maven permet
de corriger ces problmes. La qualit des mtadonnes est donc primordiale, pensez-y
si vous participez un projet qui diffuse ses binaires sur un dpt Maven.
3
Un peu plus que compiler
Jusqu prsent, Maven sest montr plutt efficace pour traiter les difficults dorganisation de notre projet, en proposant des conventions et des mcanismes automatiss qui
nous vitent de prendre des chemins hasardeux. Nous allons voir maintenant comment
il poursuit cet effort lorsque notre projet "dvie" progressivement de lexemple si
simple que nous avons utilis pour linstant.
34
Partie I
Pardon ? Maven nest pas compatible Java 5 ? Pas de panique, les choses sont plus
subtiles que cela et, heureusement pour nous, moins dfinitives. Gardez lesprit que
Maven est un projet qui a dj de nombreuses annes et une trs large base dutilisateurs. Lune des proccupations majeures des dveloppeurs est dassurer une construction de projet qui soit totalement reproductible, quel que soit lenvironnement de
dveloppement. Cette exigence est essentielle pour que vous puissiez btir vos projets
sur une base irrprochable.
Maven a t conu sur la base de la plateforme Java 1.4, version "moderne" de
lpoque. Sur ce JDK, les valeurs par dfaut des options source et target du compilateur sont respectivement 1.3 et 1.21. Par contre, sur le JDK Java 5, cette valeur par
dfaut est "1.5"2. Plutt que de laisser cette option sans valeur dterministe, ce qui
aurait rendu la construction du projet dpendante de lenvironnement utilis par un
dveloppeur, le compilateur utilis par Maven est configur, par dfaut, pour cette
valeur 1.3.
Notre code Java 5 na donc aucune chance dtre accept par le compilateur. Le choix
de Maven a t de sassurer que le projet sera construit de la mme faon quel que soit
le JDK utilis, sur la base de son exigence minimale qui est le JDK 1.4. Ce choix peut
sembler archaque mais cest la seule faon de gommer les diffrences qui existent
entre les versions de Java.
Comment modifier ce comportement protecteur mais pnalisant, qui vise juste nous
viter des dconvenues dues aux inconsistances entre versions du JDK ? Nous avons vu
que Maven associe tout projet un patron de rfrence, regroupant les tapes applicables la trs grande majorit des projets, dont la compilation des sources .java. Cette
convention nous vite de devoir explicitement indiquer Maven quand et comment
effectuer la compilation. Allons-nous devoir faire machine arrire ? Non, car Maven
prvoit galement la possibilit de reconfigurer ces tapes standard, lorsque leur fonctionnement par dfaut ne suffit plus.
1. http://java.sun.com/j2se/1.4.2/docs/tooldocs/windows/javac.html.
2. http://java.sun.com/j2se/1.5.0/docs/tooldocs/windows/javac.html.
Chapitre 3
35
Plugins
Maven confie chaque opration lmentaire de la construction du projet un plugin,
un fragment de logiciel qui se spcialise dans une tche donne. La compilation est un
exemple de plugin, mais pensez aussi lassemblage sous forme dun JAR ou linclusion de fichiers de ressources, etc. Chaque plugin propose un certain nombre doptions
et de paramtres qui permettent dajuster son fonctionnement, avec des valeurs par
dfaut qui sont choisies pour coller au mieux aux conventions de Maven et une utilisation standard. Le plugin de compilation (compiler) utilise les options source et
target avec comme valeurs par dfaut 1.3 et 1.2, correspondant la plateforme Java de
rfrence utilise par Maven.
La modification des options par dfaut dun plugin seffectue dans le fichier POM du
projet, au sein de son bloc <build> :
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.0.2</version>
<configuration>
<source>1.5</source>
<target>1.5</target>
</configuration>
</plugin>
</plugins>
</build>
Chaque plugin peut ainsi tre reconfigur. Un plugin, comme tout artefact manipul par
Maven, est identifi par le triplet [identifiant de groupe, identifiant dartefact, version].
Nous indiquons ici le plugin de compilation dont nous dsirons ajuster le fonctionnement. Le bloc <configuration> permet de lui passer des valeurs qui vont remplacer
celles par dfaut. Chaque plugin ayant son propre paramtrage, nous devons consulter
la documentation du plugin3 pour connatre toutes les options disponibles (voir
Figure 3.1).
Comme vous pouvez le constater, le plugin dispose dun grand nombre de paramtres,
qui lui permettent de rpondre sans difficult aux cas de figure les plus dlicats. En plus
des options "standard" de javac, vous pouvez par exemple utiliser un compilateur alternatif comme celui dEclipse JDT si votre projet ncessite cette option pour une raison
quelconque. Dans notre cas, seuls les paramtres source et target sont ncessaires
3. http://maven.apache.org/plugins/maven-compiler-plugin/.
36
Partie I
pour obtenir le rsultat attendu, les autres paramtres pouvant conserver leur valeur par
dfaut.
Figure 3.1
Le site de documentation du plugin compiler.
INFO
Chaque plugin Maven dispose dun site de documentation, en particulier les plugins standard, sur http://maven.apache.org/plugins/. La documentation fournit une description de
chaque option, les valeurs par dfaut utilises et, dans la plupart des cas, quelques exemples
de configuration pour les utilisations les plus frquentes. Ces sites documentaires sont gnrs partir du code source du plugin et diffuss en mme temps que lui. Ils sont donc
toujours synchrones avec la version courante du plugin.
Attention cependant, car le site web gnr correspond gnralement la version en cours
de dveloppement du plugin, aussi soyez attentif lindication "since" ajoute certains
paramtres.
Proprits
La modification du fonctionnement du plugin de compilation nous permet enfin de
valider la syntaxe Java 5 que nous avons introduite dans le projet. Ce besoin tout
Chapitre 3
37
simple a cependant ncessit une configuration significative, ce qui peut vous laisser
perplexe : pas moins de 10 lignes dans le fichier POM.xml, l ou deux attributs suffisent
dans un script Ant !
Ce principe de reconfiguration des plugins est la version "lourde" de la solution, mme
si elle a lavantage de nous ouvrir les portes de toutes les options de configuration.
Il existe cependant une autre voie, plus lgre bien quayant certaines limites. La
consultation de la page documentaire du plugin de compilation rvle que les paramtres
source et target sont associs une expression, respectivement maven.compiler.source et maven.compiler.target. De quoi sagit-il ?
Les valeurs par dfaut utilises par un plugin peuvent tre modifies via un lment
<plugin> dans le POM, mais aussi pat lexploitation dun mcanisme de Maven appel
"interpolation", qui consiste valuer au moment de lexcution les valeurs utiliser en
se fondant sur des "expressions". Celles-ci peuvent tre compares aux mcanismes
utiliss dans les applications par lexpression language des JSP. La chane
maven.compiler.source est value juste avant que Maven nutilise le plugin, en
fonction de lenvironnement dans lequel il sexcute. En particulier, cette notion
d"environnement" inclut les variables systme passes sur la ligne de commande avec
loption -D. Nous pouvons donc activer la compilation Java 5 en lanant la commande :
mvn compile -Dmaven.compiler.source=1.5 -Dmaven.compiler.target=1.5
38
Partie I
La plupart des plugins Maven proposent cette option pour leurs principaux paramtres
de configuration ; cependant, cette pratique nest pas gnralise tous les paramtres
ni tous les plugins. Il sagit plus dune bonne pratique que les dveloppeurs de plugins
devraient connatre pour satisfaire au mieux leurs utilisateurs. Dans le cas contraire,
seule loption lourde reste envisageable.
Quelques exemples bien choisis (Arnaud a bien prpar son coup) nous convainquent
rapidement des amliorations que Groovy apporterait notre projet. Reste un petit
cueil : le "projet type" utilis par Maven pour dfinir les tches excutes lors de la
construction dun projet ninclut certainement pas lexcution du compilateur Groovy !
La grande majorit des projets Java nutilisent pas ce langage aujourdhui. Il ny a donc
aucune raison pour que Maven en ait tenu compte nativement.
En consultant la documentation en ligne de Groovy4, nous constatons cependant quun
plugin Maven a t dvelopp. Il suffit de le dclarer dans le POM du projet pour obtenir cette nouvelle tape dans la construction de notre binaire. La notion de plugin (greffon) prend alors tout son sens : pour prendre en charge le besoin X, il suffit dajouter au
4. http://groovy.codehaus.org/GMaven.
Chapitre 3
39
Figure 3.2
La structure de base dun projet Maven.
La logique est plutt simple : la racine, on trouve le fichier POM qui gouverne toute
la gestion Maven du projet. Lensemble des sources est plac dans un rpertoire src,
tandis quun rpertoire target sert de zone temporaire pour toutes les oprations ralises sur le projet. Cela a au moins lavantage de faciliter grandement la configuration de
votre gestionnaire de code source ! Il suffit dexclure target (en plus des fichiers spcifiques de votre IDE) et vous tes sr de ne pas inclure par mgarde des fichiers de
travail qui nont pas tre partags.
Sous le rpertoire des sources, Maven effectue un dcoupage explicite entre ce qui fait
partie du projet ce que vos utilisateurs vont utiliser et ce qui sert doutillage de test.
Deux sous-rpertoires, main et test, marquent cette distinction.
40
Partie I
Enfin, dans chacune de ces branches, un dernier niveau de rpertoires spare les fichiers
sources par langage : java pour le code source de vos classes java, resources pour les
fichiers de ressources (configuration XML ou fichiers de proprits), webapp pour
les fichiers statiques dune application web.
Le plugin Groovy ajoute son lot de conventions qui viennent complter celles dj dfinies par Maven. Les fichiers source Groovy ont ainsi leur propre rpertoire de code
source sous src/main/groovy. Il en est de mme pour les tests crits dans ce langage
avec src/test/groovy. Ces conventions sont alignes sur celles de Maven pour obtenir
un ensemble cohrent. Dautres plugins qui apportent le support de langages autres que
Java suivront la mme logique.
Ajouter un plugin
Ces rpertoires crs pour accueillir le code, il nous reste dclarer le plugin Groovy
dans notre POM. Sur lexemple du plugin compiler, nous ajoutons :
<build>
<plugins>
<plugin>
<groupId>org.codehaus.groovy.maven</groupId>
<artifactId>gmaven-plugin</artifactId>
<version>1.0-rc-5</version>
<configuration>
<!-- les valeurs par dfaut nous conviennent trs bien :) -->
</configuration>
</plugin>
</plugins>
</build>
ASTUCE
Vous constaterez, si vous utilisez un diteur XML, que llment version nest pas obligatoire pour les plugins. Le comportement de Maven se traduit alors par prendre la
"dernire version stable disponible". Cest une fausse bonne ide ! En effet, si vous
reprenez une version de votre projet dil y a six mois pour une correction urgente, vous
risquez de ne pas utiliser le mme plugin que prvu initialement. Si la compatibilit
ascendante nest pas parfaite, attention la casse. Pour cette raison, il est fortement
recommand de toujours spcifier la version de vos plugins. partir de Maven 2.0.9,
ceux qui sont dclars par dfaut dans Maven ont une version prdfinie en interne pour
viter ce pige.
Chapitre 3
41
limite un noyau et tous les plugins qui lui permettent dexcuter des tches sont
obtenus de sa connexion au rseau, do les interminables tlchargements lors de la
premire excution !
Cependant, nos sources Groovy ne sont pas prises en compte, et les traces dexcution
de la console ne laissent entendre aucun traitement particulier de ce langage. Nous
avons d brler une tape
Plugin et tches
La notion de plugin permet Maven disoler, dans un sous-projet ddi la gestion, des
oprations lmentaires qui sont utilises pour construire divers projets. Cela ne signifie
pas pour autant quun plugin nest concern que par un seul traitement. Si lon reprend
lexemple du plugin de compilation, celui-ci doit compiler le code source Java de
lapplication, mais aussi le code source des tests. Un plugin regroupe donc des tches
lmentaires qui partagent un mme domaine.
Chaque plugin dfinit ainsi plusieurs tches (ou goals) et il ne suffit pas de dclarer un
plugin pour ajouter un traitement notre projet, nous devons galement prciser lequel
(ou lesquels) de ces traitements unitaires nous souhaitons intgrer la construction du
projet.
<build>
<plugins>
<plugin>
<groupId>org.codehaus.groovy.maven</groupId>
<artifactId>gmaven-plugin</artifactId>
<version>1.0-rc-5</version>
<executions>
<execution>
<goals>
<goal>compile</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
Un lment <execution> permet de dfinir les tches dfinies par le plugin considr
que Maven devra excuter.
Miracle, nous pouvons compiler notre code source Groovy. Sortez la boule facettes !
42
Construction du projet
Partie I
Plugins excuts
ressource:ressource
compiler:compile
gmaven:compile
surefire:test
jar:jar
install:install
deploy:deploy
Figure 3.3
Le cycle de vie du projet et les plugins qui viennent sy greffer.
Compiler en JavaScript
Avec ce putsch de Groovy sur le projet, Arnaud a russi un tour de force. Pour ne pas le
laisser sendormir sur ses lauriers, Nicolas relve le dfi de secouer une nouvelle fois
nos petites habitudes.
Notre application dispose dune interface web qui permet de saisir sa liste de
courses depuis nimporte quel navigateur. Cest le cas de trs nombreuses
applications J2EE, qui exploitent le navigateur comme environnement
universel pour sexcuter sans que vous deviez rien installer sur votre ordinateur. Il est
dailleurs trs probable que vous consultiez le solde de votre compte bancaire de cette
faon !
Les premiers jets de cette "application web" fonctionnent mais sont assez peu sexy.
Rien voir avec ces sites hauts en couleur et en effets visuels qui parsment le Web et
qui rvolutionnent notre utilisation dInternet. Nicolas sattarde donc quelques instants
sur le tableau blanc que nous utilisons pour griffonner nos dernires ides et le
tableau est rapidement noir de petits croquis, de flches en tout genre et de notes sur
le comportement idal de notre site web.
Les ractions ne tardent pas : cest bien joli, mais qui se sent les paules de faire tout
a ? Et avec quel outil ? Nous ny connaissons rien en JavaScript, le langage utilis sur
les navigateurs web pour animer les pages. Avant que la surprise ne laisse la place une
Chapitre 3
43
raction pidermique face lampleur de la tche, Nicolas lche son arme secrte :
GWT.
Figure 3.4
Notre document officiel de spcifications pour lapplication web.
INFO
Google Web Toolkit (GWT) est un outil dvelopp par Google pour offrir aux dveloppeurs
Java les portes du Web. Capable de traduire en JavaScript du code source Java, il permet
ces derniers de conserver le confort de leur langage prfr et de leur outillage habituel,
tout en dveloppant des applications web qui ragissent au moindre mouvement de souris.
La prouesse technique est impressionnante, et les portes que cela ouvre aux dveloppeurs
Java ne font encore que sentrouvrir.
Une petite dmonstration sur le PC portable qui tranait comme par hasard sur un coin
de table fait taire les derniers incrdules. Effectivement, dvelopper pour le Web nest
finalement pas si compliqu que a. Reste faire tourner cet ovni issu de la galaxie
Google dans un projet Maven ! Heureusement pour nous, dautres ont eu le mme souci
et un plugin est disponible pour marier GWT avec notre projet.
44
Partie I
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>gwt-maven-plugin</artifactId>
<version>1.1</version>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>generateAsync</goal>
</goals>
</execution>
</executions>
<configuration>
<extraJvmArgs>-Xmx512M</extraJvmArgs>
</configuration>
</plugin>
Voil qui est encourageant mais pas de script de lancement offrir notre Eclipse.
Rien dtonnant cela : la configuration dEclipse nest pas une tape standard de la
construction dun projet, a fortiori pour les utilisateurs de NetBeans ! Comment Maven
pourrait-il connatre notre intention et dterminer quelle tape de la construction du
projet nous dsirons intgrer ce traitement ?
5. http://mojo.codehaus.org/gwt-maven-plugin/.
Chapitre 3
45
Invoquer un plugin
Les commandes que nous avons passes jusquici taient de la forme mvn xxx, avec
pour xxx la phase de construction du projet que nous dsirerions atteindre, par exemple
compile. Maven permet galement dinvoquer directement un plugin, et lui seul, via
une forme diffrente de la ligne de commande :
mvn gwt:eclipse
Ici, nous ne demandons pas la construction du projet, mais lexcution isole de la tche
eclipse du plugin gwt. Il sagit dailleurs dune version contracte de la commande
complte :
mvn org.codehaus.mojo:gwt-maven-plugin:1.1:eclipse
Le raccourci est apprciable, mais il vaut mieux garder en tte cette syntaxe qui pourra
parfois se rvler indispensable.
Linvocation directe dun plugin nest gnralement utile que pour des tches annexes
du projet, comme ici la configuration de lenvironnement de dveloppement. La plupart
des plugins et des tches quils dfinissent sont prvus pour se greffer dans le cycle de
construction du projet. Il est donc inutile dinvoquer directement une tche dun plugin
qui na pas t prvu dans ce sens ; dailleurs, cela aboutirait dans la majorit des cas
une erreur.
Cette nouvelle dcouverte nous amne nous demander ce qui diffrencie dans ce
plugin GWT la tche eclipse de la tche compile. La premire sexcute seule par
invocation directe, la seconde sait se greffer dans le cycle de construction du projet.
Mais comment fait Maven pour dterminer quand lexcuter ?
Cycle de vie
Ce que nous avons jusquici qualifi de "projet type" utilis par Maven pour identifier et enchaner les tches de base dun projet Java est en ralit compos de deux
lments : le cycle de vie dun ct et les plugins et tches qui y sont attachs de
lautre.
Le cycle de vie est une srie de phases ordonnes qui doit couvrir les besoins de tout
projet. Ces phases sont purement symboliques et ne sont associes aucun traitement particulier, mais elles permettent de dfinir les tapes cls de la construction du
projet.
46
Partie I
On retrouve ainsi :
Tableau 3.1 : Le cycle de vie dfini par Maven
Phase
Description
validate
initialize
initialisation
generate-sources
process-resources
compile
process-classes
test-compile
test
package
install
deploy
Il sagit dune liste simplifie : le cycle complet dfinit de nombreuses phases intermdiaires, dont vous trouverez la description complte dans la documentation en ligne de
Maven6.
Quels que soient le projet et ses particularits, tout traitement ralis pour le "construire"
viendra naturellement se greffer sur lune de ces tapes.
Pour un projet standard (sans indication de <packaging>), Maven considre que le
binaire construire est une archive JAR. Chaque plugin propose des tches qui correspondent un traitement unitaire. Maven associe un certain nombre de tches ces
phases du cycle de vie. La tche compile du plugin de compilation, par exemple, est
associe la phase compile, et la tche jar du plugin darchivage la phase package.
Linvocation de la commande mvn deploy va alors drouler une une les tapes du
cycle de vie jusqu la phase demande (deploy), et excuter pour chacune delles les
tches des plugins qui lui sont associs :
6. http://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html.
Chapitre 3
47
Tableau 3.2 : Les plugins et les tches associs par dfaut au cycle de vie dun projet JAR
Phase
Plugin
Tche
process-resources
maven-resources-plugin
Resource
compile
maven-compiler-plugin
Compile
process-test-resources
maven-resources-plugin
testResources
test-compile
maven-compiler-plugin
testCompile
test
maven-surefire-plugin
Test
package
maven-jar-plugin
Jar
install
maven-install-plugin
Install
deploy
maven-deploy-plugin
Deploy
Maven fournit un moyen pour venir greffer dautres plugins ce cycle, en plus de ceux
quil aura associs par dfaut.
Plugins
Phases
validate
gwt:generateAsync
generate-sources
generate-resources
process-resources
compile
process-classes
test-compile
test
package
integration-test
verify
install
deploy
ressource:ressource
compiler:compile
gmaven:compile
gwt:compile
surefire:test
jar:jar
install:install
deploy:deploy
Figure 3.5
Cycle de vie du projet et plugins excuts pour chaque phase.
48
Partie I
Gnrer du code
Suite aux nombreuses volutions que nous avons apportes, notre projet est aujourdhui
capable dinvoquer des services Web SOAP pour sintgrer avec dautres applications.
Ce code a t dvelopp via lun des nombreux assistants qui peuplent les environnements de dveloppement intgr moderne. Nous lui avons fait ingurgiter le WSDL du
systme partenaire et il a gnr pour nous un squelette de code que nous navons eu
qu complter.
Lintgration de gnrateurs de code dans les environnements de dveloppement,
masqus derrire des interfaces graphiques colores et des barres de progression, nous
ferait presque oublier la complexit technique de ces outils. Nous allons pourtant tre
rapidement rappels lordre.
Aprs une migration technique importante, notre partenaire nous transmet la nouvelle
version de son contrat de service web, un nouveau fichier WSDL. Seulement Fabrice,
responsable de la mise en uvre de ce service web, est en cong aux Carabes pour un
mois. Il va donc falloir se dbrouiller sans lui.
Premire question : comment utilise-t-on ce fameux assistant de cration de service
web ? Les options sont nombreuses et, sans un bon bagage technique, il nous est difficile de savoir lesquelles choisir. La stratgie du "tout par dfaut" ne nous garantit pas la
pertinence du rsultat.
Seconde interrogation : les classes prcdemment gnres avaient-elles t modifies ? Nous pourrions craser purement et simplement le package Java correspondant
au code gnr, mais sommes-nous srs que Fabrice ny a pas fait des adaptations ?
En fouillant dans les notes de Fabrice, nous trouvons heureusement le petit guide du
dveloppeur de service web qui rpond nos questions (et donc pas besoin de le dranger
durgence durant ses vacances bien mrites).
ASTUCE
Nous ne doutons pas que, sur vos projets, vous disposiez dune documentation trs complte
et toujours jour pour dcrire ces procdures. Pensez tout de mme au temps que ncessite
la maintenance de ces documents et au temps perdu par un nophyte pour se plonger
dedans quand il en a besoin.
Cela ne signifie pas pour autant que Maven rende un systme documentaire inutile. Cependant, autant que possible, automatisez et simplifiez les choses et ayez plutt le rflexe wiki
que document de synthse valid par quinze relecteurs.
Maven propose une autre approche ce problme, une fois de plus via ses plugins.
Rappelons que, pour Maven, le rpertoire src ne doit contenir que le code source et que
Chapitre 3
49
50
Partie I
gnres pour dvelopper le code propre votre application, plutt que de venir modifier ce code et de risquer de tout perdre lors de la gnration suivante, ou de devoir
comparer deux versions et reporter manuellement vos modifications.
Le seul inconvnient de cette pratique est que le gnrateur de code sera invoqu
chaque construction du projet par Maven. Loutil de gnration peut tre assez
lourd et son lancement systmatique, pnalisant pour votre productivit. Aussi, les
plugins Maven associs utilisent gnralement des mcanismes permettant de ne
lancer la gnration que lorsque cest rellement ncessaire, soit parce que le rpertoire de gnration nexiste pas, soit parce que le fichier qui sert de rfrence a t
modifi.
7. http://code.google.com/p/flex-mojos.
Chapitre 3
51
Le fichier POM du projet propos par Franois inclut donc, par rapport un projet Java
"classique" :
m
Des dclarations classiques de dpendances vers le SDK Adobe Flex, dont les artefacts sont de type SWC et non JAR.
La dclaration du plugin flex-mojos. Le point cl est llment <extension>true</extension> qui signale Maven que ce plugin propose des complments quil faudra prendre en compte avant de dterminer le cycle de vie et les
tches excuter.
La version du compilateur Flex utiliser par le plugin. Le plugin nest pas li une
version particulire de SDK Flex, aussi lajout dune dpendance au plugin
permet de spcifier la version quil devra utiliser.
Le Listing 3.1 montre le POM utilis par Franois pour son projet qui nous fait mettre
un pied en dehors du monde Java.8
Listing 3.1 : Production dun binaire SWF
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>fr.noubliepaslalistedescourses</groupId>
<artifactId>interfaceflash</artifactId>
<version>1.0</version>
<packaging>swf</packaging>
<properties>
<flex.sdk.version>4.0.0.7219</flex.sdk.version>
</properties>
<build>
<sourceDirectory>src/main/flex</sourceDirectory>
<testSourceDirectory>src/test/flex/unit</testSourceDirectory>
<plugins>
<plugin>
<groupId>org.sonatype.flexmojos</groupId>
<artifactId>flex-compiler-mojo</artifactId>
<version>3.2.0</version>
<extensions>true</extensions>
<configuration>
<targetPlayerVersion>10</targetPlayerVersion>
<debug>false</debug>
<sourceFile>Main.mxml</sourceFile>
8. Si lutilisation de Flex depuis Maven vous intresse, retrouvez toutes les informations utiles sur le
blog de Franois : http://jroller.com/francoisledroff/.
52
Partie I
</configuration>
<dependencies>
<dependency>
<groupId>com.adobe.flex</groupId>
<artifactId>compiler</artifactId>
<version>${flex.sdk.version}</version>
<type>pom</type>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
<dependencies>
<!-- Flex SDK dependencies -->
<dependency>
<groupId>com.adobe.flex.framework</groupId>
<artifactId>flex-framework</artifactId>
<version>${flex.sdk.version}</version>
<type>pom</type>
</dependency>
...
</dependencies>
</project>
Ce fichier POM na rien de trs diffrent de ce que nous avons utilis jusqu prsent, et
pourtant il sadresse une plateforme trs diffrente de Java. Maven montre ici ses
capacits dadaptation et dextensibilit. Un simple plugin ddi un langage ou une
plateforme diffrente permet dutiliser Maven dans un cadre pour lequel il na pas du
tout t prvu initialement. Le cycle de vie du projet peut tre totalement adapt pour
des besoins trs particuliers, enchanant les tches adquates dun plugin ddi.
Nous sommes bluffs par la dmonstration de Franois, qui nous prsente une interface
web dun trs haut niveau, mais nous sommes presque plus stupfaits de la facilit avec
laquelle il a pu intgrer un langage a priori trs loign du monde Java dans notre
mcanisme de construction de projet.
Chapitre 3
53
Le plugin GWT est dvelopp dans le cadre du projet Mojo, qui est en fait plus une
communaut quun projet proprement parler. Elle regroupe des dveloppeurs qui
contribuent une grande varit de plugins ou exprimentent des ides dans un "bac
sable". Ces plugins sont associs lidentifiant de groupe org.codehaus.mojo. La liste
de ces plugins est longue et senrichit rgulirement, vous trouverez trs probablement
votre bonheur dedans.
Le plugin CXF est, lui, dvelopp en marge du projet Apache CXF, autrement dit
lquipe de dveloppement de ce projet prend elle-mme en charge son intgration avec
Maven. Ce cas est de plus en plus courant avec la place importante que prend Maven
dans le monde Java.
Le plugin flex-mojos utilise son propre dpt pour hberger ses versions, ainsi que les
dpendances spcifiques Flex utilises sur ce type de projet. Cest le cas de nombreux
plugins dvelopps lextrieur de la communaut Maven traditionnelle. Pour utiliser
un dpt non standard de plugins, il nous faut ajouter au projet la dclaration adquate :
<pluginRepositories>
<pluginRepository>
<id>flex-mojos-repository</id>
<url>http://svn.sonatype.org/flexmojos/repository/</url>
</pluginRepository>
</pluginRepositories>
Conclusion
Maven propose un cadre de dveloppement strict qui permet de complter le projet
grce de nombreux plugins sans interaction nfaste entre eux. Via son cycle de vie,
chaque plugin trouve sa place et contribue loutillage global du projet par petites
touches. Un outillage complet du cycle de vie du projet permet de contrler toutes ses
tapes en une seule commande et, surtout, regroupe toutes les infos et tous les paramtres
de configuration ncessaire en un seul endroit.
Quels que soient le projet Maven auquel vous participez et son langage, la commande
mvn install sera toujours le seul et unique point dentre pour construire le projet, en
intgrant toutes les tapes ncessaires. La structure du projet sera toujours identique et
vous permettra dtre rapidement productif, sans devoir passer par un long "guide de
dmarrage" prcisant les bibliothques utiliser et le rle de chaque paramtre.
4
Mettre en place des tests unitaires
Le petit projet initial est maintenant de lhistoire ancienne. Sous limpulsion de
contributeurs enthousiastes, de nombreuses fonctionnalits sont venues lenrichir.
Il propose aujourdhui une multitude de services tous aussi indispensables les uns
que les autres. La diversit des contributions introduit cependant une nouvelle difficult : le projet est devenu quelque peu chaotique et relativement htrogne. tel
point quil devient dlicat dintroduire une nouvelle fonction sans risquer de "casser"
quelque chose.
La solution, nous la connaissons dj. Il est ncessaire de passer par une phase de ringnierie (refactoring) pour mieux structurer notre code et le simplifier, lassouplir, le
rendre extensible, adaptable, bref : meilleur. Ce travail ncessite cependant de sassurer
que les services rendus resteront les mmes aprs ces modifications.
Aujourdhui dj, quelle que soit lvolution que lon dsire apporter au logiciel, fonctionnelle ou purement technique, nous sommes contraints dune faon ou dune autre
de vrifier les ventuelles erreurs et incompatibilits que nous pourrions introduire
involontairement. Nous passons donc beaucoup de temps tester lapplication afin de
voir si elle continue de fonctionner "comme avant".
56
Partie I
La rigueur du passage des tests, si lon considre que ltre humain se lasse vite de
tches rptitives et peu porteuses de crativit.
Automatisons !
Pour limiter ces risques, il existe une pratique simple et particulirement efficace :
lautomatisation des tests ! Un mcanisme automatique ne cote pas grand-chose
lexcution. En dehors de la machine quil monopolise, il ne rclame pas daugmentation ni de congs. Il peut tre trs rapide et ne se lasse pas de ce quon lui demande
de faire. Mme aprs des centaines de rptitions, il sera tout aussi regardant sur le
rsultat quil est cens vrifier. Nous devons donc voir les tests comme un traitement
informatique intgr dans notre projet. La cration des tests, mme si elle a un cot,
est avant tout un investissement qui nous prmunit des rgressions dans le futur et
amliore lvolutivit de notre logiciel en levant langoisse : "Je ne touche pas au cas
o je casserais quelque chose." Les tests automatiss sont un vritable vecteur pour
lamlioration de la productivit des quipes puisquils leur permettent de se concentrer sur le logiciel en toute quitude mme si une partie importante du code doit tre
refactore.
Chapitre 4
57
La solution la plus lmentaire pour mettre en place des tests automatiss consiste
intgrer dans le code des fragments de tests, en gnral sous forme dune mthode main
charge de vrifier le fonctionnement de la classe qui la dfinit, comme dans lexemple
du Listing 4.1.
Listing 4.1 : Une mthode main de test
public class ListeDeCoursesReader {
public ListeDeCourses read( InputStream in ) { ... }
/** Test automatique de la classe ListeDeCoursesReader */
public static void main( String args[] ) {
ListeDeCoursesReader reader = new ListeDeCourseReader();
ListeDeCourses lu = reader.read( new FileInputStream( "./test.list" ) );
if ( lu == null ) {
System.err.println( "FAILED : Erreur de lecture" );
System.exit( -1 );
}
}
}
Cette pratique est cependant trs discutable. Dune part, elle ncessite de passer par un
lanceur qui va excuter toutes les mthodes main des tests, lautomatisation nest donc
pas complte. Ensuite, notre projet va embarquer dans son code binaire le code de
test, qui na pas grand intrt pour les utilisateurs. Si laugmentation de la taille du
fichier JAR nest pas en soi un problme bloquant, cela nest pas conceptuellement
trs satisfaisant.
Malgr ces quelques reproches, considrons tout de mme cette option qui a lavantage
dtre simple et a dailleurs t une pratique courante en dveloppement Java.
Pour amliorer la capacit de notre test identifier un problme, nous allons contrler
le contenu de lobjet ListeDeCourses lu lors de lexcution du test. Nous nous basons
donc sur une comparaison entre un objet ListeDeCourses attendu et lobjet ListeDeCourses effectivement construit lors de lexcution du test. Pour ne pas devoir crire la
comparaison entre ces deux objets (attendu vs effectif), nous faisons appel la classe
BeanComparator de la bibliothque prouve commons-beanutils1 qui fait ce travail
pour nous en une seule ligne de code, ce qui rend le test plus simple et plus lisible.
Inutile de rinventer la roue et de venir compliquer le code alors que cette classe simplifie tellement la tche et nous permet de nous focaliser sur notre objectif : tester de
manire automatique autant de fonctionnalits que possible. Le Listing 4.2 montre cette
volution de notre mthode de test.
1. http://commons.apache.org/beanutils/.
58
Partie I
Trs fiers de notre mcanisme de test automatis, nous lanons donc la version frachement compile de lapplication sur notre serveur de test. Et l, cest la douche
froide :
ClassNotFoundException org.apache.commons.beanutils.BeanComparator
Que sest-il pass ? Lintroduction dune nouvelle bibliothque pour simplifier lcriture du test a cr des imports dans le code, imports qui ne peuvent tre rsolus sur le
serveur de test car nous navons pas ajout la bibliothque commons-beanutils lenvironnement de test. Cela naurait aucun sens car, en dehors de ce test, elle nest absolument pas ncessaire !
Faut-il alors renoncer utiliser des bibliothques dans les tests et se contenter du seul
JDK ? Bien sr que non ! Cela voudrait dire que nous plaons les tests au second plan
et que nous nous interdisons den faire quelque chose dintelligent et de facile crire.
De toute vidence, la solution de la mthode main pour tester montre de graves limites.
Utiliser un framework de test
Nous ne sommes pas les premiers faire ce constat, et la rponse existe depuis bien
longtemps travers des outils de test spcialiss pour Java, dont le plus connu dentre
eux est jUnit2.
Ces outils reposent sur des principes simples :
m
Le test associ une classe est crit dans une classe Java spare implantant ce
framework, quon nomme par convention du nom de la classe teste avec le suffixe
"Test".
Chaque test raliser est traduit par une mthode ddie dans la classe de test.
2. Il existe deux variantes majeures de jUnit, jUnit3 et jUnit4, la seconde utilisant la syntaxe java5
que nous avons retenu pour notre exemple
Chapitre 4
59
Loutillage propose des mcanismes dinitialisation et de libration qui permettent de prparer les conditions dexcution du test et de fermer proprement les
ressources aprs son excution, mme en cas derreur.
Loutillage fournit des mthodes utilitaires pour les oprations courantes de vrification du bon fonctionnement du logiciel.
Loutillage de test se charge didentifier tous les tests excuter et de les enchaner,
en fournissant au final un rapport complet des ventuelles erreurs rencontres.
Pour tester notre ListeDeCoursesReader avec jUnit, nous allons donc crire une classe
ListeDeCoursesReaderTest, y crer une mthode testLectureDeuxElements et y
transfrer notre code de test. Le Listing 4.3 montre cette transformation de notre code
Listing 4.3 : Utilisation de jUnit
import static org.junit.Assert.*;
public class ListeDeCoursesReaderTest {
@Test
public void lectureDeDeuxElements() {
ListeDeCoursesReader reader = new ListeDeCoursesReader();
ListeDeCourses attendu = new ListeDeCourses( ... );
ListeDeCourses lu = reader.read( new FileInputStream( "./test.list" ) );
assertEquals( 2, lu.size(), "liste lue de taille incorrecte" );
if ( new BeanComparator().compare( attendu, lu )!= 0 ) {
fail( "Donnes lues incorrectes" );
}
}
}
Cette nouvelle organisation nous permet de ne pas polluer le code de notre projet, sans
pour autant renoncer nos tests automatiss. Elle fournit un cadre simple pour lcriture de ces tests et des mthodes utilitaires pour nous aider les crire simplement. Elle
nous propose de prendre en charge lexcution de nos tests, en fournissant via une interface graphique un compte rendu synthtique pointant immdiatement les erreurs
rencontres. Ce rapport est en particulier parfaitement intgr dans les environnements
de dveloppement comme Eclipse, NetBeans ou IntelliJ Idea.
Lobjectif de cet ouvrage nest pas de dtailler le fonctionnement de jUnit. Nous ne
pouvons donc que vous conseiller de consulter le site junit.org et les nombreux ouvrages consacrs au sujet. Signalons cependant que jUnit nest pas le seul candidat pour
lcriture de tests et quil partage ce terrain en particulier avec son challenger TestNG et
avec sa propre version "modernise" jUnit4. Chacun a ses points forts, aussi nous vous
laissons choisir loutil le plus appropri vos besoins et vos habitudes de travail.
60
Partie I
Chapitre 4
61
Ils seront galement totalement intgrs au projet et enregistrs dans notre gestionnaire
de version.
Listing 4.4 : Accs aux fichiers de test en tant que ressources
public void testLectureDeuxElements() {
ListeDeCoursesReader reader = new ListeDeCoursesReader();
InputStream is = getClass().getResourceAsStream ( "test.list" );
ListeDeCourses lu = reader.read( is );
...
ASTUCE
Ce mcanisme daccs aux ressources de test est celui que nous vous recommandons dutiliser autant que possible. Cela sapplique lorsque vous manipulez un type abstrait comme
java.io.InputStream ou java.net.URL. Si vous devez expressment utiliser un type
java.io.File, ne supposez pas que le rpertoire courant est forcment la racine du projet
(nous verrons au Chapitre 7 que ce nest pas toujours le cas). Maven fournit la variable
systme basedir qui pointe la racine du projet. Utilisez donc :
File basedir = new File( System.getProperty( "basedir", "" ) ).getAbsoluteFile();
File monFichier = new File( basedir, "chemin/relatif" );
Le scope "test"
Nous avons vu que la bibliothque commons-beanutils nous a jou un mauvais tour.
Bien pratique pour simplifier lcriture de notre test, elle venait perturber notre application. Maintenant que le test possde sa propre classe ddie, ce problme est en principe
rsolu. Cependant, les utilisateurs dIDE font confiance leur environnement pour
grer les imports et peuvent se faire piger nouveau. Il est si facile dajouter un import
en saisissant juste le dbut du nom dune classe quil nest pas rare de terminer son
travail avec quelques imports inutiles. LIDE peut galement faire le mnage pour nous,
mais quil laisse passer une coquille par mgarde nest pas exclu.
Contrairement un projet dans les IDE courants, un projet Maven a deux visages bien
dfinis : la branche principale (src/main), portant le code de lapplication et les dpendances qui lui sont associes dans le POM, et la branche test (src/test), portant
loutillage de contrle ainsi que ses dpendances ddies. En effet, une dpendance
dclare dans le POM porte une indication de scope, qui permet Maven de savoir
quand telle ou telle bibliothque doit tre utilise par les outils de compilation. Lorsque
le scope porte la valeur test, il est exclu de lapplication et ne sera utilis que pour la
compilation et lexcution des tests.
<dependency>
<groupId>junit</groupId>
62
Partie I
<artifactId>junit</artifactId>
<version>4.7</version>
<scope>test</scope>
</dependency>
Si lassistance de lIDE nous a fait intgrer par erreur des classes normalement ddies
notre outillage de test, la compilation par Maven chouera en signalant immdiatement le problme. Nous pouvons donc faire appel tous les utilitaires possibles et
imaginables qui nous aideront crire nos tests de manire plus efficace et sans risquer
de polluer lapplication.
Le choix doutils de tests est parfois plus dlicat que le choix de linfrastructure de
notre logiciel. Pour tre pertinents et bien couvrir les besoins, les tests doivent rester
simples et performants et peuvent utiliser les ressources de nombreuses bibliothques.
La gestion de dpendances transitive de Maven nous ouvre les portes doutils de test et
de simulation trs avancs, avec une simplicit de mise en uvre dconcertante.
Le dveloppement pilot par les tests
Les tests automatiss que nous venons dajouter notre projet nous offrent un garde-fou
intressant. de nombreuses reprises, ils nous signalent quune "petite modification"
savre bien plus significative que ce que nous avions pens.
Au cours dune discussion sur les nouvelles ides que nous avons eues pour
notre projet, Vincent propose de changer le format du fichier dans lequel
nous stockons la liste de courses. Cette modification permettra de stocker
des donnes complmentaires, dont je vous laisse le soin dimaginer lutilit.
Nos tests existants permettront de vrifier que ce nouveau format ne perturbe pas le
code existant, mais Vincent va plus loin. Avant mme que nous nayons dtermin
comment nous allions lire ces nouvelles donnes depuis le fichier, il commence crire
une nouvelle mthode de test vrifiant que les informations supplmentaires ont t
correctement lues. Aurait-il "oubli" que, pour que le logiciel fonctionne, il faut un
moment ou un autre raliser son code ?
Une fois son test crit, Vincent le lance et ne semble mme pas vex de voir son cran
afficher dans un rouge sang le rsultat assez prvisible :
FAILURE
java.lang.NullPointerException
Vincent est tout simplement un adepte du dveloppement pilot par les tests (Test
Driven Development ou Test First). Plutt que de tester son code, il prfre crire des
tests qui dcrivent prcisment ses attentes, puis crire le code qui sera capable
de faire passer ses tests au vert. La diffrence est tonnamment efficace en termes de
Chapitre 4
63
structuration du logiciel. Plutt que dtre guid par des contraintes techniques ou par
des considrations de pur informaticien, chaque lment du logiciel nexiste que parce
que la bonne excution dun test ncessitait son existence. Comme chaque test est guid
par un besoin, crit avant mme que lon nait commenc se torturer lesprit avec la
ralisation, le code rpond de manire simple et juste aux besoins.
La sur-ingnierie est une drive courante de linformatique o des composants deviennent inutilement complexes au regard de la fonctionnalit rendre, simplement pour
rpondre des considrations purement techniques qui napportent rien lutilisateur.
Vincent a donc crit dabord une mthode de test simple, focalise sur sa nouvelle
ide et uniquement guide par ce quil attend du logiciel et non pas par lide quil a
derrire la tte concernant les technologies qui vont laider ou le code quil va mettre en
uvre. Aprs cette phase prparatoire quon pourrait qualifier dans un vocabulaire plus
traditionnel dexpression de besoin, Vincent est content de voir son test chouer : le
test est valide et vrifie bien quelque chose que lapplication ne fournit pas encore. Ne
riez pas, trop souvent des tests ne font queffleurer lapplication et nchouent pas si
lon supprime le code cens tre test !
Vincent commence ensuite la ralisation. Aprs quelques lignes de code, le test lanc
nouveau choue encore mais sur un cas derreur moins abrupt :
FAILURE
Assertion Failed: actual 1, expected 2
Le code commence donc se mettre en place mais ne rpond pas encore aux attentes.
Quelques minutes plus tard et aprs que les corrections qui simposent ont t apportes, le
test passe enfin au vert.
Cette faon de travailler est un moyen trs puissant de structurer ses dveloppements en
fonction du rsultat atteindre et non en rpondant nos pulsions dinformaticiens
avides de code. Une rgle de base du dveloppement pilot par les tests est quaucun
code ne doit tre crit sil nest pas rendu indispensable par un test. Autrement dit,
dune part, du code non test ne devrait pas exister, et dautre part, du code qui nest
pas guid par un besoin fonctionnel na rien faire dans un logiciel intelligemment
construit.
La ralisation du code qui rpond son test lui a permis didentifier de nouvelles
portions de code trs proches dautres dj existantes. Il aimerait bien les regrouper
dans des mthodes communes. La duplication de code est lennemi dun logiciel volutif et fiable, aussi Vincent applique le second commandement du dveloppement pilot
par les tests : DRY (Dont Repeat Yourself "Tu ne te rpteras pas").
64
Partie I
Arm de ses tests, tous focaliss sur des aspects unitaires ou fonctionnels de lapplication, il peut faire toutes les oprations de ringnierie qui lui semblent ncessaires pour
arriver un bon niveau de structuration. Chaque modification apporte est contrle par
les tests existants qui assurent ainsi que le logiciel reste fonctionnellement quivalent.
Loutillage de test en place permet prsent de se focaliser sur des aspects purement
techniques, pour ne pas dire esthtiques, concernant lorganisation de notre code.
Niveau dabstraction, volutivit, lisibilit. Chaque modification que nous lui apporterons afin den amliorer la qualit pourra tre valide dun point de vue des fonctions
rendues par lapplication : nos tests doivent tous rester au vert. Certaines modifications
lourdes et pourtant importantes nauraient jamais t ralises en confiance sans cette
garantie.
crire un test pour
une fonctionnalit
Rouge
Ringnierie du code,
sans ajout de fonctionnalit
- le test doit toujours passer
Ringnierie
Vert
Figure 4.1
Dveloppement pilot par les tests.
Le dveloppement pilot par les tests est une pratique prconise par de nombreuses
mthodes agiles3. Sa mise en uvre efficace ncessite une culture du test automatis
pour tre rellement efficace. Maven participe cette dmarche par la place quil donne
au test dans le cycle de vie du projet. Les tests vus par Maven sont des lments de
premier plan du projet.
3. On appelle "mthodes agiles" un ensemble de mthodes de travail qui cassent le mythe du projet
bien planifi pour prfrer une approche ractive. Voir http://fr.wikipedia.org/wiki/Mthode_agile.
Chapitre 4
65
66
Partie I
Maven, la compilation de ses tests choue systmatiquement : nos utilitaires ne sont pas
vus par le compilateur.
Cette situation en apparence paradoxale est simple expliquer. La majorit des environnements de dveloppement intgrs ne diffrencient pas contrairement Maven les
bibliothques utilises pour crire le code et celles associes aux tests. En rfrenant le
projet noubliepaslalistedescourses, lenvironnement donne accs toutes ses classes
et dpendances, sans distinction. Maven par contre sappuie sur le JAR qui a t
construit par chaque projet, et sur lui seul. Nos utilitaires de test ne sont accessibles
quau cours de la construction du projet qui les dfinit et pas en dehors. Le projet de
Lukas ne peut donc exploiter que les classes qui sont destines linclusion dans le JAR
final, et pas la panoplie de tests qui les accompagne.
Copier-coller ces classes est videmment hors de question, et nous ne pouvons demander Lukas de rcrire entirement ses tests sans ce code de support qui lui a fait
gagner tant de temps. La solution, Maven la fournit via le plugin jar, responsable de la
construction de notre archive.
Comme nous lavons vu, le plugin jar est attach par dfaut au cycle de construction du
projet lors de la phase package et sa tche jar construit larchive rien de trs surprenant. Ce plugin dfinit dautres tches, en particulier une qui va nous sauver la mise :
test-jar. Celle-ci permet de construire en parallle du JAR du projet un second JAR,
contenant cette fois les classes et ressources de test. Le Listing 4.5 montre la configuration associe au plugin jar pour obtenir ce rsultat. Le fonctionnement par dfaut suffit
notre besoin, aussi lajout de ce traitement ne ncessite aucun lment de configuration
particulier.
Listing 4.5 : Construction dun test-jar en mme temps que larchive java du projet
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.2</version>
<executions>
<execution>
<goals>
<goal>test-jar</goal>
</goals>
<inherited>false</inherited>
</execution>
</executions>
</plugin>
Cette seconde archive partage les mtadonnes du projet (le POM). Il ne sagit pas dun
second projet Maven contenant nos tests, mais bien dun aspect secondaire de notre
unique projet dont Maven se propose de grer la construction. La diffrenciation entre
Chapitre 4
67
Lintgration continue
Nous lavons vu, nos tests automatiss prennent toute leur valeur lorsquils sont excuts
rgulirement. Chaque dveloppeur peut compter sur eux pour vrifier quil na pas (ou
au moins, pas trop, en fonction de la qualit des tests) dtraqu lapplication avec ses
68
Partie I
dernires modifications. Cela peut mme laider identifier les points reprendre sur
des parties de lapplication quil ne connat pas bien ou structurer ses propres dveloppements.
Une autre utilisation des tests est de rendre leur passage systmatique sur une machine
ddie, afin de dtecter le plus vite possible une erreur introduite par un dveloppeur
qui naurait pas identifi le problme par lui-mme. Il ne sagit pas du tout de rechercher le mouton noir qui introduit des bogues et ne vrifie rien sur son environnement.
Il nest pas rare de crer des instabilits parce quon a oubli de diffuser un fichier sur
le gestionnaire de version ou parce quun fragment de code dpend de lencodage des
fichiers sur le systme, dun chemin particulier, ou de la version du JDK utilise.
Cette machine qui va incessamment analyser notre projet en excutant tous les tests
aura lavantage norme sur un contrleur humain de ntre limite que par sa rapidit
dexcution pour signaler les problmes. la moindre faute, elle pourra se fonder sur la
liste des dernires modifications pour signaler aux personnes concernes le problme
identifi. Venant dun automate plutt que dun collgue, ce genre de reproche est plus
facile accepter.
Ce contrle automatis et incessant fait partie (mais nest quun lment) de lintgration continue, une pratique introduite par les mthodes de dveloppement agiles. Cest
un outil puissant et facile mettre en place que nous ne pouvons que vous recommander. Mme si, dans un premier temps, vous ne lutilisez que pour contrler la bonne
excution des tests et identifier au plus tt les dfaillances de vos collaborateurs et les
faiblesses de votre application, vous constaterez rapidement ses bnfices et les bonnes
pratiques que vous pouvez en tirer.
Le serveur qui va excuter nos tests peut se baser sur lun des nombreux outils disponibles.
Nous citerons Continuum et Hudson, mais cette liste est loin dtre exhaustive.
Continuum
Continuum a t dvelopp par la communaut Maven, avec bien sr pour objectif de
prendre en charge de manire aussi intgre que possible la structure des projets Maven
et les relations de dpendance quils peuvent entretenir. Il ne se limite cependant pas
ce type de projets et peut tout aussi bien accueillir vos projets Ant ou outills par des
scripts.
Son point fort est son excellente intgration des projets Maven. Sur dtection dun
changement dans le gestionnaire de code source, Continuum va ainsi construire uniquement le projet impact puis enchaner avec tous les autres projets qui lutilisent et pourraient
tre impacts de manire indirecte par ce changement.
Chapitre 4
69
Son principal point faible est son interface web qui ne bnficie pas des raffinements
auxquels nous ont habitus les applications web modernes. Un peu trop de configuration et
de changement de page sont ncessaires pour lexploiter.
Figure 4.2
Continuum en train de surveiller les projets de Maven2.
Hudson
Cr par Kohsuke Kawaguchi, employ de SUN, pendant son temps libre, Hudson est
rapidement devenu un outil incontournable. Son cycle de dveloppement est extrmement bref, au point quil est difficile de choisir une version, la suivante pouvant apparatre dans les jours ou les heures qui suivent. Cette trs forte ractivit permet cependant
dapporter rapidement les corrections qui simposent et de proposer des fonctionnalits
nouvelles par petites touches.
Hudson nest pas ddi Maven et peut tout aussi bien accueillir des projets Ant ou
simplement bass sur des scripts. Le support de Maven, bien quarriv tardivement et
longtemps considr comme exprimental, est cependant dun bon niveau et parfaitement
fonctionnel.
Les points forts de Hudson sont la qualit de son interface web et lextrme simplicit
de son installation. Son principal point faible (en progrs constant) est lintgration en
70
Partie I
constante amlioration mais toujours perfectible des projets Maven, en particulier ceux
rpartis en plusieurs modules (voir Chapitre 6).
Figure 4.3
Hudson, lui aussi en train de surveiller la construction de Maven2.
Lequel choisir ?
Le choix de votre serveur dintgration continue va dpendre de nombreux critres.
Techniquement parlant, il faut quil soit adapt vos environnements, quil sache
communiquer avec votre gestionnaire de versions et ventuellement votre outil de
suivi de bogues. Il faudra aussi quil puisse facilement remonter de linformation aux
dveloppeurs, par mail, messagerie instantane, plugin dans lenvironnement de dveloppement ou autre. Dans tous les cas, il faudra vrifier que la compatibilit est au
rendez-vous.
Ce ne sont pas les seuls critres retenir. Nous navons vu ici quune utilisation trs
superficielle de lintgration continue, qui se contente de compiler et de tester rgulirement notre projet pour signaler les erreurs. La pratique dintgration continue va
trs au-del, comme nous le verrons au chapitre suivant. En fonction de votre utilisation, certaines fonctionnalits vous sembleront indispensables et dautres, inutiles.
Chapitre 4
71
Conclusion
Les tests unitaires sont des acteurs de premier plan pour introduire la qualit logicielle
dans le cycle de dveloppement du projet. Maven les considre comme tels et son
fonctionnement mme participe trs activement la promotion de cette pratique.
Lintgration de tests dans un projet ncessite un changement de pratiques et lappropriation de nouveaux outils, elle nest donc ni instantane, ni totalement gratuite. Le
"retour sur investissement" est cependant sans commune mesure une fois les bonnes
habitudes en place. Un projet outill par des tests rassure tout le monde sur son niveau
de qualit et sa stabilit dans le temps. Livrer un logiciel dont tous les tests sont au vert
est autrement plus rassurant pour lquipe que dappliquer les derniers correctifs en
esprant ne pas avoir introduit derreur quelques heures de la livraison.
5
Mettre en place des tests
dintgration
Nous avons vu au fil des pages qui prcdent comment outiller notre projet dun ensemble de tests automatiss qui permettent de valider son bon fonctionnement et sa stabilit. Cet apport majeur notre mode de dveloppement est un virage important qui
modifie notre organisation. Nous navons plus proprement parler une phase de dveloppement puis une phase de test, mais une combinaison des deux qui vise obtenir un
rsultat toujours meilleur.
Fort de ce nouveau paradigme, notre quipe dveloppe rapidement une relle addiction
aux tests. Nous outillons progressivement notre code pour vrifier et valider chaque
parcelle de notre application.
74
Partie I
Dmarage
du navigateur web
headless (sans visuel)
Dmarage
du micro-serveur
embarqu
Lancement
du test
Lancement
du module
GWT complet
Arrt
du navigateur
et du serveur
embarqu
Excution
du test
Temps
utile
Test
termin
Figure 5.1
La squence dopration droule par un test GWT.
Chapitre 5
75
Avec cette dfinition, nous mettons donc de ct un grand nombre de tests que nous
pourrions tout de mme automatiser : tests dinteroprabilit, tests de charge et dendurance, tests ncessitant linstallation du logiciel sur un serveur typiquement, linterface web dune application WAR
Laisser de ct une gamme aussi large de tests juste parce quils nentrent pas dans la
logique du "tester souvent" de Maven nest pas une option qui nous mnera bien loin.
Ce que nous voulons, cest intgrer dans la construction du projet de nouvelles tches
mais les conserver optionnelles pour la majorit des dveloppeurs qui ne seront pas
concerns. Le mcanisme de profil de Maven offre une solution simple pour que chaque
dveloppeur puisse activer les spcificits qui conviennent sa tche en cours, sans
perdre le bnfice davoir toute la configuration et tout loutillage ncessaire (ou du
moins le maximum) configurs dans le seul fichier POM.
Les profils
La rponse de Maven ce problme sappelle un profil. Il sagit tout simplement de
regrouper tout ce qui implique un pan de construction que nous voulons rendre optionnel. Dfini au sein dun bloc ddi, il pourra au besoin tre activ ou dsactiv selon le
dveloppeur qui intervient sur le projet. Le profil peut dfinir des plugins supplmentaires, de nouvelles dpendances ou des proprits supplmentaires.
Ce mcanisme est trs pratique dans le cadre de nos tests qui ne sont pas indpendants
de lenvironnement ou qui sont pnalisants en raison de leur dure dexcution. Le
Listing 5.1 prsente la configuration dun profil qui excutera nos tests GWT si le profil
associ est activ. Notez la configuration du plugin surefire qui le prcde, lequel
permet dexclure ces tests dans le mode de fonctionnement par dfaut. Un dveloppeur
qui na que faire de linterface web ne sera donc pas pnalis, et un dveloppeur qui
travaille dessus naura qu activer le profil associ en ajoutant sa ligne de commande
loption -Pgwt.
Listing 5.1 : Un profil ddi aux tests GWT
<build>
<plugins>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.4.3</version>
<configuration>
<excludes>**/*GwtTest.java</excludes>
</configuration>
<plugin>
</plugins>
</build>
76
Partie I
<profiles>
<profile>
<id>gwt</id>
<build>
<plugins>
<plugin>
<artifactId>gwt-maven-plugin</artifactId>
<version>1.1</version>
<executions>
<execution>
<goals><goal>test</goal></goals>
<execution>
<executions>
<configuration>
<includes>**/*GwtTest.java</includes>
</configuration>
<plugin>
</plugins>
</build>
</profile>
<profiles>
Tous ceux qui dveloppent du code GWT sont ainsi en mesure de bnficier de notre
couverture de test, sans perturber dautres dveloppeurs comme notre spcialiste de
la base de donnes que nintressent pas nos Widgets et autres ClickHandlers.
Loption -P suivie des noms des profils spars par une virgule permet dactiver la
demande les profils dsirs par lutilisateur.
Sadapter lenvironnement
Une autre utilisation des profils consiste adapter la configuration Maven du projet
lenvironnement de lutilisateur. Il est aussi possible de conditionner lactivation du
profil une spcificit de lenvironnement dexcution, par exemple le systme
dexploitation ou la version de Java qui excute Maven. Une proprit systme (dfinie
avec loption -Dnom=valeur de la ligne de commande) peut aussi servir de condition
pour activer un profil. Enfin, le profil peut tre activ en fonction de la prsence dun
fichier particulier.
Olivier, qui travaille sous Solaris, se sent un peu exclu lorsquil voit apparatre dans le projet des dpendances de type DLL pour Windows. Celles-ci
sont ncessaires pour un de nos outils de dveloppement mais elles sont
galement disponibles dans des versions pour Mac ou Linux. Plutt que dobliger
chacun de nous tlcharger ces trois variantes juste pour tre sr de satisfaire tout le
monde, Olivier utilise les profils pour tablir une liste de dpendance par type de
systme.
Chapitre 5
77
Le Listing 5.2 montre un autre cas dactivation dun profil lorsque le systme qui
excute Maven est Windows. Cette particularit est exploite pour ajouter une dpendance qui naurait aucun sens sur un autre systme : une bibliothque native DLL.
Listing 5.2 : Activation dun profil en fonction du systme dexploitation
<dependencies>
<dependency>
<groupId>com.google.gwt</groupId>
<artifactId>gwt-dev</artifactId>
<version>1.6.2</version>
<classifier>${platform}</classifier>
<dependency>
<dependencies>
<!-- profiles (activation en fonction de la plateforme) -->
<profiles>
<profile>
<id>windows</id>
<properties>
<platform>windows</platform>
</properties>
<activation>
<os>
<family>windows</family>
</os>
</activation>
</profile>
<profile>
<id>macos</id>
<properties>
<platform>mac</platform>
</properties>
<activation>
<activeByDefault>false</activeByDefault>
<os>
<family>mac</family>
</os>
</activation>
</profile>
<profile>
<id>solaris</id>
<properties>
<platform>linux</platform>
</properties>
<activation>
<activeByDefault>false</activeByDefault>
<os>
<name>sunos</name>
</os>
</activation>
</profile>
</profiles>
78
Partie I
INFO
Dans lexemple du Listing 5.2, la dpendance indique utilise la notion de classifier que
nous avons dj rencontre au Chapitre 4. Celle-ci permet de placer dans un rfrentiel
Maven plusieurs variantes dun mme artefact sous la mme identit groupId: artefactId: version. Cest la mthode recommande si vous devez driver un mme composant
en fonction du systme cible comme ici, ou distribuer une version de la mme bibliothque
avec et sans mcanisme de dbogage comme le propose le driver Oracle.
Dsactiver la demande
Un profil peut aussi tre dclar "actif par dfaut", auquel cas on considre que le fait de
ne pas excuter les tches quil dclare est une exception au mode de construction standard du projet mais qui peut se justifier dans certains cas. Un profil actif par dfaut peut
tre dsactiv ( partir de Maven 2.0.10) depuis la ligne de commande via loption -P,
mais en faisant prcder son nom du symbole "!", qui reprsente la ngation, comme en
Java. Supposons, par exemple, que votre projet exploite des rgles de codage strictes,
mais que vous admettez que vos dveloppeurs puissent vouloir tester leur code avant de
sassurer quelles sont strictement respectes. Le Listing 5.3 prsente une configuration
de ce type. La commande suivante permet de droger cette rgle le temps dune
excution de Maven :
mvn -P!codestyle install
Chapitre 5
79
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
Les profils sont ainsi un mcanisme puissant que propose Maven pour offrir plusieurs
visages un projet, sans perdre le bnfice dune configuration unique pour tous. En
activant les profils qui correspondent son rle dans lquipe, un dveloppeur peut faire
coller le comportement de Maven sa tche courante. Il ne devra pas perdre un temps
prcieux chercher de lui-mme des moyens de contournement pour des traitements
qui lui importent peu ou qui ne le concernent pas.
INFO
Le paramtre dactivation <activeByDefault> ne sapplique que lorsquon ne prcise pas
explicitement une liste de profil avec loption -P. Il ne signifie pas que ce profil est toujours
actif. Cela peut donc avoir des effets indsirables si on introduit un nouveau profil sur un
projet, car ceux qui taient jusquici "actifs par dfaut" seront alors dsactivs.
80
Partie I
XML utilis par Maven), dfinit le pilote JDBC et la connexion la base de donnes
utiliser, puis ordonne la suppression de la base, sa reconstruction selon nos scripts DDL
et enfin linjection de donnes de test de rfrence.
Il existe galement un plugin pour DBUnit qui permet dutiliser le format spcifique de
celui-ci dans le mme but.
Listing 5.4 : Prparation dune base de donnes de test "propre" avec le plugin SQL
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>sql-maven-plugin</artifactId>
<version>1.2</version>
<dependencies>
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc14</artifactId>
<version>10.2.0.3.0</version>
</dependency>
</dependencies>
<configuration>
<driver>oracle.jdbc.driver.OracleDriver </driver>
<url>jdbc:oracle:thin@localhost:1521:XE</url>
<username>user</username>
<password>pwd</password>
</configuration>
<executions>
<execution>
<id>drop-all-tables-before-test </id>
<phase>process-test-resources</phase>
<goals>
<goal>execute</goal>
</goals>
<configuration>
<srcFiles>
<srcFile>src/main/sql/drop-schema.sql</srcFile>
</srcFiles>
<onError>continue</onError>
</configuration>
</execution>
<execution>
<id>create-schema</id>
<phase>process-test-resources</phase>
<goals>
<goal>execute</goal>
</goals>
<configuration>
<srcFiles>
<srcFile>src/main/sql/create-schema.ddl</srcFile>
</srcFiles>
Chapitre 5
81
</configuration>
</execution>
<execution>
<id>create-data</id>
<phase>process-test-resources</phase>
<goals>
<goal>execute</goal>
</goals>
<configuration>
<orderFile>ascending</orderFile>
<fileset>
<basedir>${basedir}/src/test/sql</basedir>
<includes>
<include>*.sql</include>
</includes>
</fileset>
</configuration>
</execution>
</executions>
</plugin>
Si cette configuration fonctionne trs bien pour ceux qui ont install une base Oracle
eXpress, nos outils ne sont pas en mesure den installer une et de la lancer notre place.
Ils posent comme un prrequis quune base soit disponible chaque excution du test
avec les droits ncessaires pour installer les donnes de test.
Il nexiste pas (encore) de plugin Maven qui installe et configure une base de donnes
Oracle ou MySQL sur votre poste durant la construction du projet. Nous devons donc
faire confiance au dveloppeur et penser quil dispose sur son environnement dune
base de donnes fonctionnelle et correctement configure pour que nos tests puissent
sexcuter correctement. Cela est par contre possible avec dautres bases 100 % Java
comme Apache Derby ou HSQLDB.
La philosophie de Maven est justement daller contre ces prrequis, qui imposent aux
dveloppeurs de passer de longues heures mettre leur environnement au carr pour
pouvoir enfin coller aux attentes du projet. Demander chaque dveloppeur de disposer dune base de donnes, de fichiers de test ou de simulateurs fonctionnels, alors quil
nintervient que sur une sous-partie du logiciel est contre-productif.
Ici aussi, un profil ddi simpose ! Avant de voir les dveloppeurs web se
plaindre de devoir installer Oracle Express juste pour les tests, Herv dfinit
un nouveau profil db ddi cette partie spcifique de lapplication. Une
nouvelle fois, tout le monde est ravi du compromis obtenu, qui permet doutiller trs
correctement notre code sans pnaliser la productivit des dveloppeurs non concerns.
82
Partie I
Ceux qui sacharnent trouver lordre SQL ultime peuvent tester avec un outillage
adapt, tandis que les dveloppeurs web qui nont aucune ide de ce quest un " OUTER
LEFT JOIN" peuvent purement et simplement continuer lignorer et se focaliser sur
leurs propres soucis.
Figure 5.2
Un test fonctionnel crit sous Fitnesse.
1. http://www.fitnesse.org.
Chapitre 5
83
Ce plugin gre lintgration du serveur Fitnesse, sur lequel nous enregistrons nos tests
fonctionnels et son pilotage depuis une excution de Maven. Le paramtre classPathProvider, par exemple, permet de remplacer la gestion du classpath Fitnesse par celle
de Maven, grce quoi nos dclarations de dpendances sont cohrentes avec le code
excut par nos tests fonctionnels.
En une simple commande, nous pouvons demander lexcution de notre batterie de
tests et valider le fonctionnement de notre application. La simple commande mvn
fitnesse:run suffit pour nous donner en quelques minutes un rapport complet sur
ltat davancement de notre dveloppement par rapport aux attentes exprimes par nos
tests fonctionnels.
Le paramtre failOnError permet de stopper la construction du projet si les tests fonctionnels ne sont pas entirement valids, option que nous retiendrons pour automatiser
notre livraison ou pour une campagne de non-rgression entre deux versions.
Les tests fonctionnels, parfois aussi appels tests dacceptation, sont un excellent
moyen de qualifier un projet par rapport aux exigences des utilisateurs. Leur intgration
dans un projet Maven est un trs bon moyen de mesurer le taux rel de couverture des
besoins, alors que dautres outils, bass sur les tests unitaires, vont reflter la couverture
technique mais pas ladquation du code avec la demande.
2. http://mojo.codehaus.org/fitnesse-maven-plugin.
84
Partie I
Avec cette catgorie doutils et la possibilit de les utiliser dans notre construction
de projet sans installation pralable dun matriel particulier, nous ouvrons la porte
un dveloppement pilot par les besoins des utilisateurs. Si nos tests techniques,
plus ou moins unitaires, permettent de valider le fonctionnement technique de notre
application, cette nouvelle catgorie apporte une relle plus-value notre travail en
tant disponible sur chaque poste de dveloppement via une simple commande
Maven.
Chapitre 5
85
Une fois encore, nous faisons appel un plugin Maven4 pour faire le lien entre notre
projet et cet outil. Celui-ci est cependant moins abouti que ceux que nous avons rencontrs
jusquici et il nous faudra le compiler par nos propres moyens. Pas de panique, une
simple commande Maven suffit pour cela, comme lindique la page de documentation
du plugin. Si vous voulez viter chaque utilisateur cette tche, soyez un peu patient et
attendez la lecture du Chapitre 6.
Nos scnarii ont t enregistrs sous forme de fichiers jmx, le format utilis par jMeter.
Nous suivons la convention du plugin jmeter en les plaant dans notre projet sous src/
test/jmeter. Aprs une configuration minimale, il ne nous reste plus qu invoquer la
commande mvn jmeter:jmeter pour envoyer notre application les 50 requtes par
seconde qui vont vrifier sa bonne stabilit sous la charge :
<plugin>
<groupId>org.apache.jmeter</groupId>
<artifactId>maven-jmeter-plugin</artifactId>
<configuration>
<includes>
<include>consultation-50parSeconde.jmx</include>
<include>miseAJour-50parSeconde.jmx</include>
</includes>
</configuration>
</plugin>
Cette intgration suppose que notre application est en cours de fonctionnement sur le
serveur lorsque nous lanons la charge. Nous verrons au Chapitre 8 quil est galement
possible dutiliser lautomatisation par Maven pour assembler notre application web,
configurer un serveur dapplication de test et dmarrer le tout juste avant dexcuter ce
type de test.
Intgration continue
Le serveur dintgration continue est utilis pour linstant pour valider lexcution de
nos tests unitaires. Lobjectif est quil ragisse trs vite pour nous signaler une maladresse ou une dfaillance de lun de nos neurones, ce qui est plus frquent quon le
voudrait.
4. http://wiki.apache.org/jakarta-jmeter/JMeterMavenPlugin.
86
Partie I
Avec tous nos nouveaux profils, comment configurer lintgration continue ? Nous
voulons une couverture aussi complte que possible, mais sans rduire le temps de
raction du serveur. Une pratique courante est davoir une intgration continue en
plusieurs passes :
1. Le serveur principal, qui scrute notre gestionnaire de code source pour identifier la
moindre de nos modifications, est configur pour ragir au plus vite. Il nexcute
que les tests unitaires et ventuellement quelques contrles complmentaires peu
coteux.
2. Un second serveur vient en complment. Il effectue une construction du projet
plus pousse et passe les tests dintgration plus consommateurs de ressources. Le
lancement de ce serveur est pilot depuis le premier serveur, suite une construction
russie.
Bien sr, cela suppose de disposer de davantage de machines disponibles, mais
noubliez pas ce que peut coter un bogue identifi tardivement sur un projet, surtout si
cest pour constater au final quil sagit dune tourderie, dun "TODO" laiss ngligemment dans le code, dun copier-coller maladroit, ou dune petite modif sans grande
importance qui en a finalement eu plus que prvu. Tout cela alors quon dispose de tout
loutillage ncessaire pour identifier de telles neries. Les machines ne dorment pas, ne
se plaignent pas, et surtout ne relchent jamais leur attention lorsquil sagit dpier nos
dfaillances !
Conclusion
Lorsquon pousse la logique doutiller lapplication de tests automatiss, on peut aller
trs loin, et de nombreux outils vont venir nous pauler dans cette tche. Le Web fourmille dailleurs de nouvelles ides sur le sujet, qui deviendront peut-tre les standards
de dveloppement de demain. Maven prvoit les mcanismes ncessaires pour venir les
greffer dans la construction du projet, au prix parfois de quelques acrobaties techniques
tant les dfis relever peuvent tre complexes.
La Figure 5.3 rsume les outils que nous venons dvoquer, ce qui est loin de couvrir
toute ltendue de loutillage de test disponible mme en ne considrant que les outils
open-source. On y voit le positionnement de chaque outil en fonction du niveau
dabstraction, proche du code ou bien du fonctionnel, et de la spcialisation dun outil
vis--vis dune technologie donne.
Les profils permettent de rendre optionnelles toutes ces tapes dlicates ou coteuses et
limitent limpact quelles peuvent avoir sur lensemble de lquipe alors quelles nen
concernent quune petite partie. Tester efficacement une application est une tche tellement
Chapitre 5
87
large quelle ne peut pas se rsumer quelques plugins. Si vous ne devez retenir quune
chose, cest que tout cet outillage peut prendre sa place dans votre configuration Maven
et gagnera en homognit. Placez vos scripts de test sous SVN et voyez comment
configurer leur excution depuis Maven. Ceux qui vous suivront vous en remercieront
pour le temps que vous leur ferez gagner.
Niveau dabstraction
Fitnesse
Selenium
jMeter
GWTTestCase
jUnit
Figure 5.3
Positionnement de nos outils de test.
Partie II
Maven en entreprise
Dans cette deuxime partie, nous allons confronter Maven des contraintes assez particulires, celles du monde de lentreprise. Ici, rgnent la loi et lordre, mais aussi
lurgence et le manque de moyens. Il faut faire bien trs bien, mme avec les gens
dont on dispose. Il faut respecter la lettre le cahier des charges, rpondre aux critres
de qualit et de traabilit, tre capable tout moment de passer la main un autre
dveloppeur pour faire face des fluctuations deffectif.
Maven est un projet n dans le monde de lopen-source, fond sur la collaboration
bnvole de dveloppeurs venus dhorizons trs varis. Aussi tonnant que cela puisse
paratre, une communaut de ce type est ce quil existe de plus exigeant : les volontaires
ne prennent aucun plaisir passer de longues heures corriger un bogue, ils apprcient
peu de voir leur code "bouscul" par un autre dveloppeur qui a choisi des rgles dcriture diffrentes, et rechignent expliquer longuement au petit nouveau les secrets de
leur code. Ils sont donc les premiers vouloir dfinir et appliquer un cadre commun,
des rgles de lisibilit, et soutiller en consquence pour que toutes les tches rbarbatives ou risques soient automatises.
Nous allons voir dans quelle mesure la communaut open-source Maven a devanc les
attentes du monde de linformatique professionnelle, en proposant, via son outil, une
gestion de projets, dune part, trs propre et discipline et, dautre part, trs simple et
accessible tous.
90
Maven en entreprise
Partie II
Nos compres prennent bien du plaisir sur leur projet de gestion de liste de courses. De
nombreuses fonctionnalits et technologies de pointe en ont fait un outil riche et
attrayant, si bien quune petite communaut dutilisateurs commence rclamer les
prochaines versions avec impatience. Les choses aboutissent de faon inespre : un
investisseur, un "business angel" la recherche de la perle rare, leur propose de passer
du statut damateur celui de professionnels de linformatique en montant une start-up
pour porter le projet. LesOutilsIndispensablesDeLaMnagre.com est n !1
1. Alors que Maven devenait un outil de plus en plus utilis, quelques dveloppeurs du projet ont
fond en 2004 une socit ddie au support et au dveloppement de leur bb. Mergere tait n.
Laventure a tourn court et a donn naissance en 2007 deux socits qui continuent de soutenir le
dveloppement de Maven, Sonatype et Devzuz (rachete depuis par Exist Global).
Le logo de lentreprise de notre "histoire romance dun projet fictif" est un clin dil cette aventure
humaine qui montre un autre visage du dveloppement open-source.
6
Gestion avance des dpendances
Notre projet commence prendre une tournure "intressante" du point de vue de ses
fonctionnalits. Sous le capot, par contre, cest un peu un mlange htroclite de technologies diverses, chacune ayant apport sa petite touche ldifice.
Jusquici, nous nous tions contents dajouter des dpendances, sans y regarder de trop
prs. Nous avons dj constat que cela pouvait avoir des effets de bord en introduisant
des doublons dans nos bibliothques. Nous lanons donc une analyse un peu plus stricte
de nos dpendances. Premire tape, reconstruction de lintgralit du projet sur un
poste de dveloppement frachement install.
92
Maven en entreprise
Partie II
Alternatively, if you host your own repository you can deploy the file there:
mvn deploy:deploy-file -DgroupId=com.oracle -DartifactId=ojdbc14 -Dversion
Path to dependency:
1) fr.noubliepaslalistedescourses:noubliepaslalistedescourses:jar:1.0.0-SNAPSHOT
2) com.oracle:ojdbc14:jar:10.2.0.2.0
---------1 required artifact is missing.
for artifact:
fr.noubliepaslalistedescourses:noubliepaslalistedescourses:jar:1.0.0-SNAPSHOT
from the specified remote repositories:
central (http://repo1.maven.org/maven2),
Chapitre 6
93
Figure 6.1
Recherche dun artefact via un moteur de recherche spcialis.
La licence sous laquelle elle est distribue, ce qui peut dans certains cas tre rdhibitoire (pensez, par exemple, aux conditions particulires de certaines licences
propritaires ou la licence GPL qui sapplique par "contamination" au projet dans
son ensemble).
Lintgralit de ces mtadonnes nest cependant pas toujours disponible ce qui est fort
dommageable. En particulier, linformation de licence devrait tre plus gnralement
indique car elle peut fortement impacter les projets qui utilisent une dpendance.
94
Maven en entreprise
Partie II
INFO
La licence GPL sapplique des logiciels libres et autorise lutilisation totalement gratuite
du logiciel considr. Elle impose cependant que la modification ou lutilisation du logiciel sous GPL dans un autre logiciel ne puisse se faire que dans les mmes conditions de
licence.
Dit plus simplement, lutilisation dune bibliothque sous GPL impose que votre projet soit
dvelopp sous cette licence. Si votre projet est usage interne, ce nest pas ncessairement
un problme (bien que cela soit sujet interprtation), mais si vous envisagez de le diffuser,
limpact est norme. Cela tant dit, certaines licences propritaires sont largement aussi
contraignantes lorsquon lit le dtail des petites lignes ;).
Linformation de licence ntant pas toujours disponible, il nest pas possible dautomatiser
de manire fiable lanalyse des licences sur un projet. Ce serait cependant une fonctionnalit
trs intressante de Maven.
Chapitre 6
95
outils) qui comprendra entre autres le fameux pilote. Dans ce cas bien prcis, nous
pouvons indiquer une dpendance system sous la forme :
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc14</artifactId>
<version>10.2.0.3.0</version>
<scope>system</scope>
<systemPath>${env.ORACLE_HOME}/client/java/ojdbc14.jar</systemPath>
</dependency>
Le scope system utilis ici permet de pointer vers un emplacement du poste de dveloppement pour accder une ressource locale qui ne peut pas tre gre par le mcanisme de tlchargement des dpendances, pour des raisons lgales la plupart du temps.
Les dpendances de ce type sont accompagnes dun lment supplmentaire systemPath (qui nest pas valide en dehors de ce cas). Ce chemin indique lemplacement
physique de lartefact.
videmment, ce cas de figure correspond une lecture stricte du contrat de licence
Oracle, et, pour des questions pratiques, vous prfrerez trs certainement partager
entre dveloppeurs dune mme quipe le fichier JAR tlcharg une fois pour toutes.
Il est trs improbable quOracle vous envoie ses brigades antipirates pour violation de
la licence, surtout si vous venez de lacheter pour installer la base de donnes sur votre
serveur bi-processeur quad-core1 assortie dun contrat de support ;-).
Nous pourrions aussi tre tents de dtourner ce scope et dintgrer le JAR dans le
gestionnaire de code, ce qui permettrait chacun den disposer dune manire simple
sans se poser plus de questions :
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc14</artifactId>
<version>10.2.0.3.0</version>
<scope>system</scope>
<systemPath>${basedir}/lib/ojdbc14.jar</systemPath>
</dependency>
Cela nous vite de devoir changer le fichier la main. Cependant, stocker des binaires
dans notre gestionnaire de code source est quelque peu contre-nature. Par ailleurs, si
chaque projet qui utilise une base Oracle doit intgrer un rpertoire lib, nous allons tre
tmoins de la multiplication rapide des fichiers JAR sur nos postes de dveloppement.
1. Le cot dune licence Oracle est fonction du nombre de cur. Je vous laisse imaginer ce que cela
peut donner
96
Maven en entreprise
Partie II
ASTUCE
Plutt que de regrouper nos dclarations de dpts dans la configuration, nous pouvons les
placer dans le fichier settings.xml utilis pour configurer Maven. Le gestionnaire de dpt
Nexus peut mme gnrer ce fichier avec les dclarations adquates.
Chapitre 6
97
Ces sommes de contrle sont lquivalent de nos empreintes digitales. Un bit modifi
dans le JAR donnera une somme de contrle diffrente. Cest donc un excellent
moyen pour valider un tlchargement, toujours sujet un risque de dfaillance du
transfert rseau.
Ce contrle, Maven le fait de manire systmatique et totalement transparente du
moins tant que le contrle nchoue pas ! Dans notre cas, la bibliothque tlcharge ne correspond pas aux sommes de contrle mises disposition dans le dpt
Maven.
Ce nest cependant quune alerte car, dans un monde imparfait, certaines sommes de
contrle mises disposition sont malheureusement incorrectes. Dans le doute, nous
tlchargeons nouveau le pilote JDBC Oracle. Il est vrai que la connexion ADSL nest
pas trs en forme aujourdhui, sans parler de ce satan virus qui a infect notre rseau la
semaine dernire.
Le rsultat est sans appel : le second fichier tlcharg, une fois install dans notre
dpt priv, corrige le problme. Peut-tre aurions-nous constat un problme immdiat avec ce pilote, peut-tre ne serait-il apparu que trs tardivement mais, dans tous les
cas, remonter jusqu lorigine du problme aurait t bien dlicat. Qui aurait lide de
mettre en question le JAR Oracle alors quil y a tant de raisons pour que notre application
ne fonctionne pas ?
Rebelote : mais o est javax.jms ?
Notre problme de dpendance sur le pilote JDBC Oracle est enfin rsolu de manire
satisfaisante. Mais voil que nous obtenons nouveau un message derreur comparable,
concernant cette fois lAPI Java Messaging Service (JMS pour les intimes).
Missing:
---------1) javax.jms:jsm:jar:1.0.2b
Try downloading the file manually from the project website.
La solution est toute trouve, puisque le problme est quivalent celui que nous avons
rencontr avec Oracle. Un rapide coup de fil Carlos permet de mettre disposition le
JAR manquant sur notre dpt priv.
Cependant, il ne sagit pas dun produit propritaire mais bien dune API standard de
Java, et mme pas spcialement exotique ou rcente. Comment est-il possible que
Maven ne dispose pas de cette bibliothque ? Il doit bien y avoir des millions de dveloppeurs lutiliser chaque jour sur des projets JEE.
98
Maven en entreprise
Partie II
Ce second exemple montre bien quel point la problmatique des licences ne doit pas
tre nglige. Si, honntement, personne ne lit attentivement les dtails de ces textes
plus ou moins abscons, leur influence sur un projet peut tre norme. Le tlchargement automatique des bibliothques par Maven est bien pratique mais tend nous
faire oublier que nous ne vivons pas dans un monde de Bisounours o tout est gratuit
et librement diffusable. Chaque bibliothque introduit des contraintes dutilisation,
parfois les restrictions dune licence commerciale, parfois les obligations dune
licence libre.
Chapitre 6
99
2. http://repo2.maven.org/maven/.
100
Maven en entreprise
Partie II
Moralit : la gestion dun dpt nest pas prendre la lgre. Il ne sagit pas simplement de pallier les manques du dpt existant, mais aussi de sassurer de lunit de
notre dpt et de sa cohrence avec ce qui est disponible en ligne.
Mtadonnes
Les choses se compliquent franchement lorsque nous commenons utiliser des
composants en version SNAPSHOT.
Nous utilisons une version SNAPSHOT du plugin GWT pour la compilation de notre
interface web. Rappelez-vous que ce mot cl la fin dun numro de version indique
quil sagit dun artefact en cours de dveloppement, sujet modifications. Autrement
dit, Maven va tenter, intervalles rguliers, den tlcharger une mise jour. Ce sont les
mtadonnes qui lui indiquent si une nouvelle version est disponible. Par dfaut, Maven
va les consulter toutes les vingt-quatre heures.
Nous avons d faire nos propres modifications dans ce plugin pour le faire fonctionner
selon nos besoins. Nous les avons diffuses lquipe qui le dveloppe, mais nous ne
pouvons attendre quelles soient acceptes. Nous avons donc plac dans le dpt priv
une version modifie du plugin. Pour que celle-ci soit utilise, nous devons mettre
jour le fichier de mtadonnes associ, sans quoi Maven ne verra rien de nouveau et ne
la prendra pas.
Carlos doit donc manuellement fusionner le fichier de mtadonnes quil a obtenu du
dpt officiel contenant le plugin avec les donnes de notre propre version. Voil un
travail bien passionnant quil va en plus falloir rpter chaque correction ! Ici aussi,
un outillage adquat simpose.
Chapitre 6
101
certains dpts depuis le poste de lutilisateur. Nous pouvons donc facilement forcer
Maven ne plus accder directement central, mais utiliser un serveur miroir sous
notre contrle et dont nous pourrons matriser la disponibilit et le contenu.
INFO
Pour les utilisateurs de Windows, le $HOME est le rpertoire C:\Documents and
Settings\votreNom, et sous Windows Vista ou Windows 7 sous C:\Utilisateurs\votreNom.
La notion de HOME est videmment plus naturelle pour les "unixiens" et autres "macistes".
<settings>
<mirrors>
<mirror>
<id>private</id>
<mirrorOf>central</mirrorOf>
<url>http://repository.noubliespaslalistedescourses.fr</url>
</mirror>
</mirrors>
<settings>
Un miroir de central
Notre premire ide est dtablir un site miroir du dpt central de Maven, ce qui nous
permettra de faire abstraction de la connexion Internet lorsque celle-ci est dfaillante,
ou tout simplement dconomiser la bande passante.
Lide est simple, facile mettre en uvre avec les outils courants. Nous constatons
cependant trs vite quelle a ses limites. Dune part, le miroir occupe plusieurs gigaoctets pour un grand nombre de bibliothques obsoltes ou totalement dnues dintrt
pour notre dveloppement. Ensuite, nous ne disposons toujours daucun outil pour
maintenir de manire fiable et ergonomique le contenu de ce site. Les mtadonnes
Maven peuvent tre compltement aberrantes, les artefacts dupliqus en de nombreux
endroits, sans quaucun outil daudit nous en informe. Bref, cette solution napporte
rien de plus, il faut un outil ddi.
Un gestionnaire dartefacts
En marge du projet Maven, la communaut des dveloppeurs a cr le projet "Maven
Repository Manager", devenu par la suite Archiva 3. Cet outil nest pas seul dans cette
catgorie et doit faire face la concurrence de Nexus 4 ainsi que dArtifactory5. Tous
3. http://archiva.apache.org.
4. http://nexus.sonatype.org.
5. http://artifactory.jfrog.org.
102
Maven en entreprise
Partie II
sont disponibles en open-source, les deux derniers proposant une option de support
professionnel qui peut tre indispensable si lon considre quune entreprise confie la
productivit de ses dveloppements ces outils. Pour ne pas faire de jaloux, nous
avons choisi de proposer une capture dcran pour chacun (voir Figures 6.2 6.4).
Ces outils sont des applications web ddies la gestion de dpt Maven. Ils assurent
un grand nombre de fonctionnalits :
m
miroir dun autre dpt, typiquement pour conserver un cache local de central et/ou
dautres dpts ;
La fonctionnalit de miroir est probablement celle qui vous fera installer Archiva pour
votre entreprise. En disposant dun miroir sous votre contrle du dpt central, vous
pourrez conomiser la bande passante de votre accs Internet, ne pas dpendre de la
bonne sant dInternet et obtenir des temps de rponse impressionnants pour les
demandes dartefacts dj placs dans le cache.
Cest en effet ce que Carlos met en place : notre dpt priv sert dsormais la fois dhbergement pour nos bibliothques non publiques et de
miroir pour les tlchargements depuis central. Le gestionnaire fonctionne en mandataire (proxy) : pour chaque demande dartefact non encore plac
dans le miroir, il va consulter les dpts configurs et complter le cache en consquence. Ainsi, les demandes suivantes seront traites immdiatement, sans dpendance Internet. Ce fonctionnement est nettement moins consommateur quun
miroir complet du dpt central dont nous nexploiterons quune infime partie des
gigaoctets de bibliothques.
Chapitre 6
103
En fonction des besoins des projets, Carlos va rapidement ajouter dautres dpts la
configuration : le dpt java.net apparat vite indispensable car il contient un certain
nombre dAPI Java standard ; le dpt de JBoss, qui propose les dernires versions
dHibernate ; le dpt SpringSource, qui offre les dernires versions MileStone du
framework Spring ; et ainsi de suite
Plutt que de nous obliger dclarer un <mirror> dans notre fichier settings.xml
chaque nouvel arrivant dans la configuration du gestionnaire de dpt, Carlos met en
place un dpt virtuel, comme le montre la Figure 6.2. Dsormais, sous lappellation
public, se cachent cinq dpts de bibliothques, dont nous compltons au besoin le
contenu via linterface dadministration. Notre fichier settings.xml volue alors comme
suit :
<settings>
<mirrors>
<mirror>
<id>releases</id>
<mirrorOf>*</mirrorOf>
<url>http://repository.noubliespaslalistedescourses.fr/content/groups/public</url>
</mirror>
</mirrors>
<settings>
ASTUCE
La syntaxe <mirrorOf>*</ mirrorOf> permet dintercepter toute tentative de Maven
daccder un dpt quel quil soit, et de la rediriger vers notre gestionnaire. Nous sommes
ainsi assurs quaucune bibliothque ne sera utilise sans avoir t mise en cache sur notre
serveur et prvue sur notre liste de dpts.
Si vous prfrez diffrencier les dpts contenant des snapshots, utilisez alors la syntaxe
combine <mirrorOf>*,!codehaus.snapshot< mirrorOf> et dfinissez un second miroir
pour chacun des dpts snapshot auxquels vous accdez.
Les mcanismes daudit permettent Carlos de contrler la bonne sant de son dpt.
Il peut mme programmer des purges et obtenir des statistiques dusage. Enfin, le mcanisme de gestion des droits des utilisateurs lui permet de dlguer certaines tches ses
collgues. Certains dentre nous sont ainsi autoriss publier sur le dpt les artefacts
de nos composants communs, sans pour autant risquer de compromettre la cohrence
globale.
Lnorme point fort dun gestionnaire de dpt sur un simple serveur HTTP est quil
prend en charge les mtadonnes Maven, fusionnant plusieurs dpts la vole. Du
point de vue de lutilisateur, le gestionnaire apparat alors comme un unique dpt.
104
Maven en entreprise
Partie II
Figure 6.2
Configuration dun dpt dans Nexus.
La gestion manuelle des mtadonnes est complexe et source derreur ; son automatisation est un point fort de ces outils.
Les outils dindexation et daudit fournissent une synthse des problmes identifis, et
la programmation de tches de fond permet de purger et de corriger automatiquement
les erreurs courantes dans le dpt sans intervention humaine. La Figure 6.3 montre par
exemple le rapport daudit sur un dpt administr par Archiva, et les diffrents problmes
quil a su y dtecter.
Le gestionnaire de dpt permet aussi une recherche globale, fournissant une vue
graphique des mtadonnes, comme le montre la Figure 6.4. La recherche peut seffectuer sur le nom de lartefact, mais peut aussi se baser sur une classe dfinie par une
bibliothque ou servir identifier un JAR en calculant son empreinte et en la comparant
lindex. Le gestionnaire expose galement ses index pour une intgration dans les
environnements de dveloppement (voir le Chapitre 9). Enfin, un espace de stockage
permet la diffusion des dveloppements au reste de lquipe, servant de dpt "publicpriv".
Chapitre 6
Figure 6.3
Rapports daudit dArchiva.
Figure 6.4
Page de recherche dArtifactory.
105
106
Maven en entreprise
Partie II
Conclusion
Plein de bonne volont, Carlos a vite compris que la gestion dun dpt Maven nest
pas aussi simple quil y parat. La gestion purement manuelle trouve ses limites et est
bien incapable de prendre en charge la complexit lie la quantit et la diversit des
artefacts. Un outil ddi comme Archiva est non seulement utile mais rapidement indispensable. Ses fonctionnalits annexes sont incontournables pour une gestion fiable du
dpt interne.
Notre quipe de dveloppement est dsormais sereine face la gestion de ses dpendances. Nous passons systmatiquement par notre serveur Archiva via la syntaxe
<mirrorOf>* et sommes assurs de ne pas dpendre volontairement ou non dun dpt
non configur dans notre gestionnaire de dpt. Nous ne sommes plus fondamentalement dpendants de laccs Internet et pouvons obtenir en un temps record les dpendances de nos projets. Enfin, nous pouvons au besoin publier en interne les artefacts qui
nous manqueraient.
7
Quand le projet devient trop lourd
Notre application a fait un joli bout de chemin. Dun embryon de projet avec trois classes, elle est devenue un vaste logiciel couvrant des accs une base de donnes, la
communication avec des services web, un module dauthentification des utilisateurs, de
nombreux mcanismes dadministration et de supervision, sans parler de notre interface
web et de nos diverses extensions pour le poste client. Tout cela ncessite de multiples
bibliothques, sans mme parler des nombreux outils de test. Il est temps de donner au
projet un peu plus de structuration pour y voir plus clair.
Un projet un artefact
Une rgle de base que nous avons rapidement comprise avec Maven est quun projet ne
peut produire quun seul artefact. Inutile donc de chercher contourner la logique de
loutil pour faire de notre projet une hydre cinq ttes qui serait capable dun ct
de produire lapplication web et de lautre le module dadministration, sans revoir la
structure Maven qui laccompagne.
INFO
Cette affirmation nest pas tout fait exacte et nous lavons dj vu au Chapitre 4 : la notion
de classifier permet dattacher plusieurs artefacts un projet, cependant ceux-ci partagent
ncessairement le mme POM et ne peuvent constituer que des variantes ou des artefacts
secondaires.
108
Maven en entreprise
Partie II
avons fait avec cette contrainte en crant autant de fichiers POM que nous avions de
composants indpendants construire.
Le premier cueil que nous rencontrons, suite aux nombreux outils et rgles de
dveloppement que nous avons mis en place, est la duplication de la configuration
Maven entre les diffrents POM. Les mmes plugins, les mmes paramtres, les
mmes versions de dpendances sont multiplis dans chacun de ces fichiers sans
mutualisation.
Face au formalisme XML du fichier POM, notre premier rflexe est de rechercher un
mcanisme dimport de fragments XML. Cest typiquement ce que permet Ant ou la
plupart des outils bass sur XML. On retrouve ainsi souvent dans les projets Ant
denvergure un build.xml accompagn dun build-common.xml. On retrouve exactement le mme mcanisme pour la dclaration de services web dans un fichier WSDL.
La balise <xs:import> permet de dcomposer le document XML en sous-parties plus
simples ou focalises sur un domaine particulier.
Grosse dception : le schma XML qui dirige la syntaxe du fichier POM ne prvoit
aucune balise <import>, <include> ou quoi que ce soit dquivalent.
Hritage
Maven utilise certes un format XML pour lcriture du POM, format par ailleurs
trangement verbeux compar dautres outils, mais il ne faut jamais perdre de vue
quil ne sagit pour lui que dune reprsentation de son modle interne. Les dveloppeurs de Maven ont donc choisi non pas une logique de morcellement par inclusion, mais une logique dhritage, trs familire tout dveloppeur Java. Un POM
peut hriter dun autre POM et reoit les attributs dfinis par son parent, sauf sil les
redfinit lui-mme.
Comme en Java, un POM ne peut avoir quun seul parent, dclar par la balise
<parent> ! Ce parent est lui-mme considr comme un artefact Maven. Il est donc
identifi par le triplet groupId: artifactId: version.
<project>
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>fr.noubliepaslalistedescourses</groupId>
<artifactId>noubliepaslalistedescourses-parent</artifactId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>noubliepaslalistedescourses</artifactId>
</project>
Chapitre 7
109
ASTUCE
Le fait de dclarer un parent permet de supprimer linformation de groupId et de version que
nous partageons avec lui. Cest une pratique trs courante qui assure par la mme occasion
lhomognit des sous-projets avec leur parent commun.
La configuration et les plugins dclars dans le POM parent seront ainsi appliqus
tout projet qui dclare cet hritage. Voil la rponse notre problme de mutualisation !
Nous pouvons mme aller au-del, en spcifiant un super-parent qui dfinira une configuration Maven propre notre organisation et applicable tous ces projets. On y trouvera, par exemple, la configuration des plugins lis nos rgles qualit et des serveurs
propres nos machines de dveloppement.
Cette pratique est mme recommande par Maven, cest ce quon appelle un peu
pompeusement un "corporate POM". Les donnes qui y sont places sont souvent plus
descriptives que techniques mais elles dfinissent au moins un endroit unique commun
tous. Il nest pas rare quun POM de ce type utilise un numro de version rduit un
seul chiffre, vu quil nest pas rellement sujet des volutions mineures ou correctives.
110
Maven en entreprise
Partie II
Maven lui-mme est un bon exemple de cette pratique : le projet est dcompos en de
nombreux modules qui hritent dun POM parent commun, qui lui-mme hrite du
POM parent Apache, commun tous les projets de la fondation du mme nom.
org.apache:apache:6
org.apache.maven:maven-parent:12
org.apache.maven:maven:2.1.0
Figure 7.1
Hirarchie des POM Apache Maven
Parent "naturel"
Lhritage dun POM parent simplifie lexistence mais elle ncessite cependant que
nous disposions dans notre dpt Maven du POM en question. Sa mise au point se
complique donc singulirement, car nous devons linstaller chaque modification avant
de pouvoir constater ses effets sur les projets qui en hritent.
Maven a heureusement prvu le coup : en plus de lidentification par le triplet groupId :
artifactId : version, triplet qui nous est maintenant familier, la balise <parent> propose
un lment inhabituel, <relativePath>. Comme son nom lindique, il fournit le chemin
physique daccs ce POM parent partir de la racine du projet courant. Et pour
combler notre dsir den faire le moins possible, Maven prvoit une valeur par dfaut
pour cet lment : "../pom.xml".
Autrement dit, Maven va rechercher avant toute chose le POM parent dans le rpertoire
pre de notre projet sous rserve que les indications de groupe, dartefact et de version
concordent. Cette recherche hirarchique est un mcanisme puissant qui va profondment orienter votre faon de travailler. Chaque projet pourra ainsi se dcomposer en
sous-modules sous forme de sous-rpertoires. Chaque groupe pourra organiser facilement son information en rassemblant tous ses projets sous une arborescence commune,
dont la racine hbergera un majestueux corporate POM.
ASTUCE
Cela est particulirement efficace si vous utilisez un gestionnaire de version du code comme
Subversion. Celui-ci permet, en effet, de dfinir des alias, permettant de construire une structure virtuelle. Il est ainsi possible davoir depuis Subversion une vision trunk / corporate /
projet / module tout en conservant une gestion locale classique projet / trunk / module.
Chapitre 7
111
Si cette organisation ne vous convient pas, vous pouvez comme toujours utiliser
dautres conventions et affecter la balise <relativePath> le chemin qui vous
convient. Vous perdrez cependant les avantages des conventions : plus de configuration,
obligation pour chaque nouvel arrivant de sadapter aux habitudes locales.
Mutualiser
Nous avons donc un mcanisme de mutualisation en place. Que pouvons-nous
mutualiser ?
Dune part, toutes nos dclarations de plugins et de proprits peuvent tre remontes
dans ce POM commun. Nous ne conserverons dans un module donn que ce qui lui est
totalement spcifique. Cela allge la configuration mais ne rsout pas un problme sur
lequel Stphane a d sacharner pendant de trop longues heures.
Stphane a t confront une incohrence dans nos dpendances. Notre
module dadministration utilisait en effet une version dHibernate diffrente
de notre application web. Si cela peut ne pas tre fondamentalement gnant,
cest tout de mme peu plaisant et source dennuis. Il a donc cherch sassurer dune
faon ou dune autre que nos diffrentes bibliothques taient utilises dans des
versions cohrentes sur nos divers sous-projets. Tche ingrate et pnible, vu le nombre
impressionnant de dpendances.
Gestion des dpendances
Un lment du fichier POM que nous navons pas encore utilis rpond ce besoin, il
sagit du <dependencyManagement>. Cette balise nest utile que dans le cadre dun
POM parent, ce qui explique que nous ne layons encore jamais rencontre. Comme la
balise <dependencies>, elle se compose dune suite de dpendances mais, contrairement elle, il ne sagit ici que de dfinir les versions par dfaut de ces dpendances.
Notre fichier POM parent va ainsi lister quelle version de chaque bibliothque fait
office de rfrence sur le projet. Dans chaque sous-projet, nous pourrons alors dclarer
nos dpendances sans indication de version, auquel cas celle indique par le dependencyManagement sera utilise.
Autre avantage de cette pratique, si une bibliothque est introduite par la gestion transitive des dpendances, et mme si nous ne lutilisons pas explicitement dans nos projets,
nous pouvons tout de mme imposer lutilisation dune version prcise via le dependencyManagement.
112
Maven en entreprise
Partie II
ASTUCE
La bibliothque commons-logging est extrmement rpandue et pourtant dcrie par
certains. Il est donc difficile de lexclure dun projet car la transitivit des dpendances la fait
rapparatre chaque fois quon tente de lexclure. Il existe cependant une solution qui
ressemble un hack mais qui est trs pratique : utiliser une version inexistante de cette
bibliothque, dclare en dependencyManagement.
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>99-does-not-exist</version>
<scope>provided</scope>
</dependency>
La gestion centralise des versions est une pratique simple qui assure la cohrence des
projets dcomposs en modules. Elle nempche pas au besoin un module de dclarer
explicitement une version autre que celle recommande par le POM parent, pour bnficier dune fonction particulire.
De la mme faon, si les rgles de lentreprise limposent, un corporate POM peut dfinir les versions valides et supportes des bibliothques, que chaque projet pourra alors
utiliser en toute confiance.
Hriter dun corporate POM juste pour partager la dclaration dun <dependencyManagement> est cependant une contrainte un peu lourde, tant donn quon ne peut hriter
que dun seul POM parent. Maven, depuis sa version 2.0.9, propose une autre option
via import, un scope particulier. Une dpendance marque de ce scope ne sera pas
ajoute au classpath du projet. Par contre, sa dclaration <dependencyManagement>
sera "importe" dans le projet comme si elle y avait t copie-colle. Cette option
permet ainsi de construire des POM communs dfinissant des versions des bibliothques courantes dont vous avez valid la bonne intgration. Avec la multiplication des
frameworks, un POM indiquant les versions compatibles entre Spring, Hibernate,
Wicket, Hibernate-validator, AspectJ et EH-Cache ne sera pas un luxe pour lancer rapidement un projet sans avoir ce problme grer !
Gestion des plugins
Au mme titre que pour nos dpendances, les versions de nos plugins Maven ne doivent
pas tre ngliges. Mme en supposant quaucune rgression ne soit constate entre
Chapitre 7
113
deux versions dun mme plugin, lutilisation de versions incohrentes est source de
bizarreries, voire de bogues trs dlicats identifier.
Le POM parent peut, l aussi, nous aider via son lment <pluginManagement>.
Comme pour la gestion des dpendances, il nous permet de centraliser les versions des
plugins utiliss par chaque module du projet.
Le format du fichier POM nimpose pas de dclarer pour chaque plugin utilis un
numro de version. Il est cependant fortement recommand de fixer cette version car
sans cela, Maven considre que vous dsirez utiliser la dernire version stable du
plugin. Si les dveloppeurs font trs attention la compatibilit ascendante, ils ne sont
pas labri dune rgression et peuvent au fil de versions successives dprcier puis
supprimer certaines fonctionnalits ou certains paramtres. Si vous intervenez sur un
projet ancien aprs quun plugin a subi de telles volutions, Maven utilisera la dernire
version et votre projet ne pourra pas tre construit lidentique, voire ne pourra plus
tre construit du tout !
Indiquer systmatiquement la version des plugins comme si llment <version> tait
obligatoire est contraignant et source dhtrognit dans un projet multimodule. Le
pluginManagement va permettre de centraliser au niveau du projet parent les versions
de tous les plugins utiliss.
Fort de ces nouveaux concepts, Raphal reprend les POM du projet pour
centraliser notre gestion de version. <dependencyManagement> et <pluginManagement> sont renseigns aprs une revue complte de tous nos fichiers
POM. La tche est complexe et source derreurs tant les risques doubli sont nombreux.
Raphal cherche donc un moyen pour sassurer quil na omis aucune dclaration de
version pour un plugin. Par ailleurs, il voudrait tre sr qu lavenir un plugin ajout
dans un module ne risquera pas de passer entre les mailles du filet. Si aucun de nos
POM ne dclare de version pour les plugins, nous savons que par mimtisme les
nouveaux plugins seront dclars de la mme manire.
Raphal trouve la solution ce problme dans le plugin enforcer. Celui-ci ne contribue
pas la construction du projet mais fait partie dune catgorie un peu particulire de
plugins qui visent outiller lutilisation de Maven. Enforcer va analyser notre modle
de projet pour vrifier certaines rgles. Lune des rgles prdfinies exige justement de
vrifier que chaque plugin du projet a une version correctement dfinie.
Listing 7.2 : Utilisation du plugin Enforcer
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
114
Maven en entreprise
Partie II
<executions>
<execution>
<id>enforce-versions</id>
<goals>
<goal>enforce</goal>
</goals>
<configuration>
<rules>
<requirePluginVersions>
<message>Dfinissez plugin.version !</message>
</requirePluginVersions>
</rules>
</configuration>
</execution>
</executions>
</plugin>
Enforcer ne fait pas une analyse de notre fichier POM en tant que document XML, ce
qui serait peu utile puisque la version du plugin peut tre dfinie dans un parent ou dans
un bloc <pluginManagement>. Il utilise le modle objet du projet qui est le rsultat de
lanalyse de notre POM et de ceux dont il hrite. Si une version est dfinie quelque part,
il saura donc la dtecter et, linverse, il saura dtecter son absence !
Enforcer propose de nombreuses autres rgles dusage de Maven permettant de sassurer que le projet est utilis selon les bons usages ou les contraintes spcifiques dfinies
par le projet. Il peut ainsi vrifier que le dveloppeur utilise une version prcise de
Maven ou du JDK, mais aussi que certains fichiers existent (ou nexistent pas),
quaucun SNAPSHOT nest utilis en dpendance, ou encore interdire lutilisation de
certaines dpendances (par exemple, pour viter des problmes de licence).
Chapitre 7
115
Maven va surtout tenir compte des dpendances quils peuvent avoir les uns pour les
autres et ordonnancer son processus de construction en consquence. Les binaires
rsultants seront donc toujours cohrents avec ltat du code source de lensemble des
modules.
Voil une fonctionnalit dterminante pour Stphane. Jusquici, notre projet dapplication web contenait la fois les pages web mais aussi toute la partie back-end de lapplication : rgles mtier, accs la base de donnes et exposition de services web.
Le dcoupage de notre sous-projet webapp en modules permet disoler physiquement
chaque couche de notre architecture. Un module pour notre domaine mtier accueillera
nos objets ListeDeCourses, Promotion et BonneAdresse. Un module permettra disoler
nos services mtier. Un troisime se concentrera sur laccs notre base de donnes, un
autre lexposition de nos services mtier sous forme de services Web, et ainsi de suite.
Chaque module, recentr sur un besoin ou sur une technologie particulire, va voir sa
liste de dpendances fondre et se spcialiser.
Il sera alors ais dassurer des rgles darchitecture du type "seule la couche base
de donnes peut faire appel Hibernate". Il suffit que les autres modules naient pas de
dpendance Hibernate pour quune erreur de codage saute aux yeux la premire
compilation !
Ce recentrage sur une technologie simplifie nettement le dveloppement lorsque
lquipe est organise par domaine de comptence. Notre spcialiste de la persistance
JPA va pouvoir donner libre cours son imagination. Outils de test spcialiss et
gestion fine des dpendances sont sa disposition pour forger son module selon ses
habitudes et les bonnes pratiques du domaine.
Hritage "naturel"
Les mcanismes de modules et dhritage ne sont pas ncessairement lis lun lautre,
cependant ils se compltent de manire naturelle. Il est trs frquent que le POM parent
soit celui qui dclare un projet comme module. En fait, les cas o une autre organisation
est ncessaire sont assez rares et rpondent des contraintes dorganisation trs particulires. La structure hirarchique des projets est donc une structure trs courante pour
les projets Maven, gnralement reflte par lorganisation physique des rpertoires.
Et lintgration continue ?
Comment va se comporter notre serveur dintgration continue face ce nouveau
dcoupage en modules ? Les outils que nous avons retenus supportent parfaitement
cette approche de Maven. Ils vont donc identifier chaque module comme un projet
ajouter dans la configuration de lintgration continue.
116
Maven en entreprise
Partie II
Dtection
dune modification
Enchane la construction
Figure 7.2
Raction du serveur dintgration continue une modification.
Chapitre 7
117
soit dclarer un grand nombre de dpendances optionnelles, auquel cas les utilisateurs devront eux-mmes aller la pche aux informations pour reconstituer la liste
de dpendances.
Dans les deux cas, les utilisateurs de Maven sont pnaliss, et ceux qui ne lutilisent pas
ne sont pas beaucoup plus avancs dans leur gestion manuelle des dpendances.
Les modules au service de larchitecture
Le dcoupage en modules permet aussi de renforcer nos rgles darchitecture logicielle.
Si notre structuration JEE impose par exemple que "seule la couche mtier est autorise
manipuler les objets de la couche daccs la base", la dclaration des dpendances
permet dinterdire tout autre module de lutiliser : en labsence de dpendance sur le
module persistance, aucun risque de le voir utilis par mgarde ! Fini la mauvaise
surprise de dcouvrir un tag JSP qui effectue sa propre requte en base pour construire
une liste de slection.
Conclusion
Le mcanisme dhritage est une originalit de Maven par rapport aux autres outils
orients script qui utilisent une logique dinclusion. Il en rsulte une mutualisation trs
structurante et trs puissante du projet en modules. Un projet Maven est ainsi rapidement dcompos en modules spcialiss dans un domaine ou une technologie. Le dveloppement dun de ces modules gagne en clart, focalis sur un aspect prcis de
lapplication, sans pour autant compliquer la construction du projet. Un simple mvn
install depuis le projet de plus haut niveau enchane les compilations de tous les
modules pour produire un livrable cohrent.
8
Maven et JEE
Notre application noubliepaslalistedescourses est fin prte pour une ouverture au
public. Nous ne disposons cependant pas de nos propres serveurs et faisons appel un
hbergeur. Celui-ci nous propose un magnifique service dhbergement JEE surveill
24 heures sur 24 par une quipe de spcialistes. Autant laisser faire les pros. Chacun
son mtier !
Le monde de Java ct serveur est un monde en "AR" : JAR, WAR, RAR, EAR se ctoient
dans un ballet un peu dconcertant darchives Java et de descripteurs de dploiement.
Souvent dcri, le modle JEE est pourtant solidement implant et continue de progresser avec une refonte significative dans sa mouture JEE6. Maven ne pouvait pas faire
limpasse sur ce modle, sur ses limites et sur les bonnes pratiques de dveloppement
qui laccompagnent.
120
Maven en entreprise
Partie II
Si vous ntes pas familier avec la norme JEE ou si vous voulez en avoir une description
plus fine et moins biaise que notre rsum de quelques lignes, nous vous recommandons
lintroduction disponible sur le site de SUN1.
liaison
Annuaire JNDI
Source de donnes
Descripteur de dploiement
Application web (WAR)
Descripteur de dploiement
Descripteur de dploiement
Base
de donnes
Figure 8.1
Structure dune application selon le modle JEE.
Cette structure soulve de nombreuses critiques, qui ne sont pas lobjet de ce livre.
Nous ne nous attarderons donc pas dessus. Quoi quon en pense, JEE est une norme
largement implante et supporte, et il nous faut la suivre dune faon ou dune autre si
nous voulons dployer notre belle application sur le serveur dhbergement.
Construire une archive web WAR
La premire tape consiste crer larchive WAR de notre application web, en incluant
son descripteur de dploiement. En tant que fichier binaire, un WAR nest rien dautre
quune archive JAR avec une extension spcifique, donc rien de bien compliqu. Nous
devons cependant suivre la structure dfinie par la norme JEE, en particulier le rpertoire WEB-INF qui doit contenir :
m
un sous-rpertoire classes avec le code compil de nos servlets et des autres classes
ncessaires notre application ;
1. http://java.sun.com/developer/technicalArticles/J2EE/Intro/.
Chapitre 8
Maven et JEE
121
Sur un projet utilisant un rpertoire lib fourre-tout pour placer ses bibliothques, le troisime point serait trait avant mme quon ne se pose la question, mais sur notre projet
Maven ?
Vincent sattaque la construction automatise de notre WAR. Il trouve
rapidement un alli de choix dans le plugin war de Maven. Celui-ci a t
conu pour rpondre de la manire la plus souple et la plus transparente qui
soit ces contraintes dassemblage. Ce plugin va btir dans le rpertoire de construction (target) la structure ouverte de larchive WAR partir des lments de notre projet
et de nos dclarations dans le POM. Il va donc y recopier tous les lments statiques de
notre application web (pages html, images, scripts), ainsi que nos classes compiles
par le plugin compiler, notre descripteur de dploiement et nos bibliothques du tout
cuit !
Cerise sur le gteau, Vincent na mme pas besoin de dclarer explicitement ce plugin
comme nous lavons fait jusquici : puisque notre projet ne produit pas un JAR, il
remplace la dclaration de <packaging> pour indiquer la construction dune archive
WAR. Ce packaging, support par dfaut par Maven, provoque automatiquement une
slection diffrente des plugins associs par dfaut aux phases du projet, et en particulier lactivation du plugin war lors de lassemblage.
Vincent aurait-il tir le gros lot en prenant en charge cette tche ? Une ligne de
configuration diter en tout et pour tout, cest plutt reposant ! Eh bien non ! Au
lancement de notre application sur le serveur de test Tomcat, nous avons droit une
erreur qui pourrait faire sourire si nous tions un 1 er avril, mais qui nous laisse
perplexes :
ClassCastException: fr.noubliepaslalistedescourses.servlets.LoginServlet is not a
javax.servlet.Servlet
Nous devons explorer un peu plus la logique de JEE pour comprendre. Un serveur JEE
isole chacun des composants quon y dploie afin quils ne se perturbent pas mutuellement. Cette isolation se fait via des chargeurs de classes ddis. Notre application web
aura donc son propre chargeur de classes, incluant les bibliothques de notre WEB-INF/
lib et nos classes de WEB-INF/classes. Celui-ci hrite dun chargeur pre qui contient
les classes du serveur dapplication permettant la mise en uvre de lAPI servlet. Le
serveur sera donc en mesure de manipuler nos servlets parce que nous partageons avec
lui les classes de cette API. La Figure 8.2 compare cependant ce modle thorique et ce
que nous observons.
Lorsque le serveur dapplication tente dinitialiser un de nos servlets, il manipule tout
naturellement le type javax.servlet.Servlet, partir des classes prsentes dans son
chargeur de classes. Notre servlet LoginServlet a cependant t instanci dans le
122
Maven en entreprise
Partie II
chargeur de classes de lapplication web ; aussi, pour que tout fonctionne bien, il faut
que le type javax.servlet.Servlet, lorsquil est manipul depuis lapplication web,
soit le mme que depuis le code du serveur dapplication.
Situation thorique
Situation actuelle
Chargeur de classes
de lapplication web
Chargeur de classes
de lapplication web
WEB-INF/classes
WEB-INF/classes
...LoginServlet.class
...LoginServlet.class
WEB-INF/Lib
*.jar
Chargeur de classes
du serveur dapplication
Commons/lib
*.jar
WEB-INF/Lib
Servlet-api-2.5.Jar
LoginServlet
implements
Servlet
LoginServlet
implements
Servlet
ClassCastException
Chargeur de classes
du serveur dapplication
Commons/lib
*.jar
Servlet
Servlet-api.jar
Servlet-api.Jar
Figure 8.2
Comparaison de la structure des chargeurs de classes : thorie vs pratique.
Chapitre 8
Maven et JEE
123
bien le cas. Il existe cependant un autre scope, provided, qui est trs proche avec une
nuance significative : il dclare une dpendance ncessaire pour compiler et sexcuter
mais qui est fournie par lenvironnement dexcution, typiquement notre serveur JEE.
La modification suivante sur nos dpendances corrige donc ce problme assez dboussolant et nous permet enfin de lancer lapplication web sur notre serveur Tomcat.
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifacId>
<version>2.5</version>
<scope>provided</scope>
</dependency>
Construire un EJB
Notre exploration du monde JEE se poursuit avec un Entreprise Java Bean, cest--dire
un macrocomposant mtier qui sera potentiellement distribuable sur lensemble de
notre cluster.
INFO
Quoi, nous navons pas de cluster ? Pourquoi avoir choisi un EJB alors ? Sans vouloir faire de
lanti-JEE, disons que les EJB ont longtemps tran de lourdes casseroles car ils taient appliqus sans quon en comprenne le rle dans larchitecture. Jusqu lmergence de JEE5 et de
JEE6, qui les dpoussirent sensiblement, leur utilisation tait mme largement dcrie au
profit de modles lgers dont SpringFramework est le fer de lance.
Nous avons donc isol notre code mtier dans un module (voir le Chapitre 7) ddi, charg de construire un composant rutilisable. Fort de son
prcdent succs, Vincent se porte volontaire pour explorer la "mavenisation"
de cet aspect de notre application.
La mme recette donne le mme rsultat, ce qui finit par nous faire penser que Vincent
a dcidment le nez fin : <packaging>ejb</packaging> dans le POM suffit pour changer la configuration par dfaut du cycle de vie et produire un EJB. La seule chose que
nous devrons y ajouter est la configuration de la version de lAPI EJB que nous voulons
utiliser, savoir EJB3 ce qui nest pas la valeur par dfaut (2.1).
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-ejb-plugin</artifactId>
<version>2.1</version>
<configuration>
<ejbVersion>3.0</ejbVersion>
</configuration>
</plugin>
124
Maven en entreprise
Partie II
Cette formalit passe, nous obtenons lEJB tant attendu, dont nous pouvons tester le
dploiement sur un serveur de test OpenEJB.
Il nous reste faire le lien avec notre application web. Celle-ci doit disposer des classes
client de lEJB, cest--dire de la partie de lEJB qui dfinit son utilisation (interfaces,
objets paramtres). Cela ne va pas nous coter beaucoup defforts puisque le plugin ejb
a la bonne ide de crer une archive avec ces classes pour nous, en ajoutant simplement
sa configuration <generateClient>true</generateClient>. Nous obtenons donc au
final deux archives Java :
m
Dans notre application web, il nous suffit donc de dclarer une nouvelle dpendance
vers ce client pour pouvoir utiliser notre EJB :
<dependency>
<groupId>fr.noubliepaslalistedescourses</groupId>
<artifactId>noubliepaslalistedescourses-ejb</artifactId>
<version>1.0.0-SNAPSHOT</version>
<type>ejb-client</type>
</dependency>
Reste faire le lien entre les deux composants, via les descripteurs de dploiement.
Lobjet de ce livre nest pas de vous faire un expos complet sur JEE ; pourtant, nous ne
pouvons pas honntement vous laisser sans rponse si prs du but Les Listings 8.1 et
8.2 montrent les deux descripteurs de dploiement de notre application, le premier
permettant lEJB de sidentifier et de demander une ressource de type base de
donnes, le second permettant lapplication web dobtenir une rfrence vers notre
EJB, potentiellement install sur un autre serveur, voire distribu sur un cluster.
Listing 8.1 : Descripteur de dploiement de notre EJB
<?xml version="1.0"?>
<!DOCTYPE ejb-jar PUBLIC
'-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 1.1//EN'
'http://java.sun.com/j2ee/dtds/ejb-jar_1_1.dtd'>
<ejb-jar>
<enterprise-beans>
<session>
<ejb-name>
ListeDeCoursesEJB
</ejb-name>
<home>
fr.noubliepaslalistedescourses.ListeDeCoursesHome
</home>
<remote>
Chapitre 8
Maven et JEE
fr.noubliepaslalistedescourses.ListeDeCourses
</remote>
<ejb-class>
fr.noubliepaslalistedescourses.ListeDeCoursesBean
</ejb-class>
<session-type>Stateless</session-type>
<transaction-type>Container</transaction-type>
<resource-ref>
<res-ref-name>jdbc/appDB</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
<description>
Accs JDBC la base de donnes
</description>
</resource-ref>
</session>
</enterprise-beans>
</ejb-jar>
125
126
Maven en entreprise
Partie II
Chapitre 8
Maven et JEE
127
Pour chaque dpendance que nous voulons voir apparatre dans ce chemin de classes
commun, et donc exclure de notre WEB-INF/lib, il suffit dindiquer le statut optionnel
de la dpendance : <optional>true</optional>. La dclaration peut sembler un peu
contre-nature, puisque dans la majorit des cas la dpendance en question nest pas du
tout optionnelle. Il sagit, avouons-le, dun dtournement de la notion de dpendance
optionnelle, qui, de toute faon, na pas vraiment de sens pour un projet WAR.
Dans notre projet EJB, nous appliquons au plugin ejb la mme dclaration <archive>
que pour le plugin war. LEJB produit aura alors dans son MANIFEST une dclaration
de classpath la place de linclusion de ses dpendances. Il ne nous reste plus qu
dclarer ces dpendances dans notre projet EAR pour que celui-ci les intgre dans
larchive EAR et quelles soient ainsi partages entre nos deux composants JEE.
Pour viter un travail fastidieux de cohrence entre les trois modules, nous remontons
dans le projet parent ces dclarations de dpendances, qui deviennent alors elles-mmes
mutualises. Comme dclaration de dpendances, notre projet application web ne
contient alors que les bibliothques spcifiquement web quil emploie. La Figure 8.3
indique la structure finale de notre projet Maven.
POM parent
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>1.4</version>
<optional>true</optinal>
</dependency>
POM EJB
<archive>
<manifest>
<addClasspath>true</addClasspath>
</manifest>
</archive>
EJB
MANIFEST.MF
Classpath: ...
POM WAR
<archive>
<manifest>
<addClasspath>true</addClasspath>
</manifest>
</archive>
POM EAR
Figure 8.3
Multiprojet JEE avec mise en commun des dpendances via lEAR.
WAR
MANIFEST.MF
Classpath: ...
EAR
commons-io.jar
128
Maven en entreprise
Partie II
Tester
Nous savons dsormais construire notre archive dentreprise en une seule
ligne de commande, respectant la lettre la spcification JEE. Mais Vincent
ne veut pas en rester l : quid des tests de nos composants ? En particulier, si
nous savons les tester unitairement ou un niveau intgration (voir le Chapitre 5), la
partie web reste le parent pauvre. Par dfinition, nos pages web produites par des JSP,
composants JSF ou servlets, ne peuvent tre testes que lorsquelles sont hberges par
un serveur JEE ou, au minimum, un moteur de servlet. Comment contrler le bon
enchanement de nos pages, la remonte correcte des donnes, le fonctionnement
global de notre application ?
Ce dont Vincent rve, cest dun outil qui ferait ce que nous devons faire la main
chaque modification du code : assembler lapplication, la dployer sur un serveur de
test, la dmarrer, puis lancer notre navigateur et enchaner quelques crans pour constater le rendu HTML dune page particulire. Eh bien rjouissons-nous, cet outil de rve
existe !
Selenium
Selenium2 est un outil qui nest pas limit au monde Java mais sy intgre trs bien. Il
sagit dun systme complet denregistrement et de pilotage du navigateur web des
fins de test rien que a.
Il se compose de deux parties :
m
Un outil de pilotage, qui va rejouer le scnario enregistr sur un navigateur. Selenium lance et dirige le navigateur de votre environnement, remplaant lutilisateur
humain.
Le grand intrt de cette approche par rapport de nombreux autres outils de test est
que lon peut tester une application web dans un vritable navigateur, avec ses particularits, ses bogues, sa faon bien lui dinterprter les balises HTML et le code
JavaScript.
Lenregistreur peut sauvegarder le scnario de test selon de nombreux formats, dont
deux vont particulirement nous intresser. Le premier est une simple table HTML,
listant les actions ralises sur le navigateur (cliquer, attendre la page suivante).
2. http://seleniumhq.org/.
Chapitre 8
Maven et JEE
129
Le second utilise notre bon vieux langage Java et le framework de test jUnit. Cette
seconde option nous permet dditer le scnario pour y ajouter les contrles qui nous
plaisent en utilisant notre langage de programmation habituel. Nous navons donc pas
apprendre les secrets dun nouveau langage !
Le Listing 8.3 montre le code dun test Selenium utilisant la syntaxe Java. Du point de
vue du programmeur, lAPI de Selenium offre une vision de trs haut niveau du navigateur
sous contrle, ce qui rend la programmation trs rapide et agrable.
Listing 8.3 : Test Selenium en syntaxe Java
import com.thoughtworks.selenium.*;
import junit.framework.*;
import java.util.regex.Pattern;
public class SimpleTest extends SeleneseTestCase
{
public void setUp()
{
setUp( "http://localhost:8080/", "*iexplore" );
selenium.open( "noubliepaslalistedescourses.home" );
}
public void testLogin()
{
selenium.type( "login", "Vincent" );
selenium.click( "submit" );
selenium.waitForPageToLoad( "5000" );
assertTrue( selenium.isElementPresent( "salut" ) );
}
}
Si la syntaxe du test est celle de jUnit, lexcution dun test Selenium ncessite un peu
plus que le simple framework de test. Selenium repose sur un composant contrleur,
charg de lancer le navigateur de la machine hte et den piloter le comportement. Nous
devons donc intgrer le dmarrage de ce contrleur dans notre processus de construction
Maven si nous voulons en exploiter la puissance :
m
Collecter le rsultat du test et le consolider pour lintgrer dans les comptesrendus dexcution de Maven (et faire chouer le build si les tests ne passent pas).
130
Maven en entreprise
Partie II
Chapitre 8
Maven et JEE
131
car cest lui qui est charg de lexcution de nos tests unitaires, et il ne sait pas diffrencier
sans notre aide les tests Selenium des tests plus classiques.
Une premire solution est dutiliser des rgles de nommage pour diffrencier facilement les deux catgories de tests. Nous navons alors qu configurer Surefire avec des
patrons complmentaires dinclusion/exclusion pour que chaque test se droule dans la
phase adquate. Le Listing 8.5 montre la configuration dans le fichier POM qui met en
uvre cette stratgie. Les tests Selenium sont suffixs Selenium au lieu de Test pour
les diffrencier.
Listing 8.5 : Configuration du plugin Surefire pour excuter nos tests Selenium
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<executions>
<execution>
<id>integration-test</id>
<goals>
<goal>test</goal>
</goals>
<phase>integration-test</phase>
<configuration>
<includes>
<include>**/*Selenium.java</include>
</includes>
</configuration>
</execution>
</executions>
</plugin>
Une autre solution consiste crer un second projet, destin aux tests dintgration,
dans lequel nous les placerons, ce qui vite toute ambigut. La configuration est alors
plus simple, et nous disposons dun emplacement ddi pour la dfinition de nos tests
dintgration.
Les deux approches sont valides et couramment appliques selon les gots de chacun.
La premire utilise de manire assez logique les phases *integrations-test de
Maven, la seconde isole cette catgorie de tests un peu hors normes dans un projet ddi
qui concerne une catgorie diffrente de dveloppeurs.
Nous savons donc lancer un navigateur et lui faire suivre un scnario prdfini. Reste
le faire pointer vers notre application. Mais au fait, o est-elle notre application ? Nous
avons bien une archive WAR, mais sans serveur o la dployer, elle naffichera jamais
de page HTML !
132
Maven en entreprise
Partie II
Cargo
Cargo3 est un autre outil majeur pour notre bote outils de test. Son objectif est de
prendre en charge linstallation dun serveur JEE, sa configuration, son dmarrage et le
dploiement de composants JEE, le tout pour tous les serveurs existants ( lexception
notable de Websphere, rcalcitrant toutes les tentatives) et via une API simple et
homogne vaste programme !
Dans notre cas, nous allons utiliser Cargo pour excuter notre application sur un
serveur JBoss. Lautomatisation quoffre cet outil par le biais de son plugin Maven est
telle quil propose de tlcharger pour nous le ZIP de ce serveur, de linstaller dans un
rpertoire temporaire et den configurer une instance la demande lors de la construction de notre projet. Tout a en une seule ligne de commande, cest tout de mme
pas mal. Bien sr, la configuration est un peu moins facile que pour un plugin plus
"simple" (voir Listing 8.6). Cet extrait de notre POM dfinit les paramtres dutilisation
de Cargo :
m
Les composants JEE qui seront dploys sur ce serveur avant de passer la phase
integration-test. Nous indiquons lartefact de notre application web ainsi quun
fichier XML, dans un format spcifique de JBoss, qui nous permet de dfinir laccs
notre base de donnes de test.
3. http://cargo.codehaus.org/.
Chapitre 8
Maven et JEE
<goal>start</goal>
</goals>
</execution>
<execution>
<id>stop-container</id>
<phase>post-integration-test</phase>
<goals>
<goal>stop</goal>
</goals>
</execution>
</executions>
<configuration>
<container>
<!-- Configuration du serveur ("container") pilot par Cargo -->
<containerId>jboss42x</containerId>
<zipUrlInstaller>
<url>http://downloads.sourceforge.net/jboss/jboss-4.0.2.zip</url>
<installDir>${java.io.tmpdir}/cargoinstalls</installDir>
</zipUrlInstaller>
<timeout>600000</timeout>
<output>${project.build.directory}/jboss42x.log</output>
<append>true</append>
<log>${project.build.directory}/cargo.log</log>
<dependencies>
<!-- Ajout du driver de la base de donnes -->
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc14</artifactId>
</dependency>
</dependencies>
</container>
<!-- Configuration du dploiement de l'application web -->
<configuration>
<type>standalone</type>
<home>${project.build.directory}/jboss42x</home>
<properties>
<cargo.logging>high</cargo.logging>
<cargo.jvmargs>
-XX:PermSize=512m -XX:MaxPermSize=1024
-XX:+CMSPermGenSweepingEnabled
-XX:+CMSClassUnloadingEnabled
</cargo.jvmargs>
<!
Quoi, vous ne connaissiez pas l'option CMSClassUnloadingEnabled ? ;p
-->
</properties>
<deployables>
<deployable>
<!-- Dploiement d'une DataSource JDBC Oracle -->
<location>${build.testOutputDirectory}/oracle-ds.xml</location>
<type>file</type>
</deployable>
133
134
Maven en entreprise
Partie II
<deployable>
<!-- Dploiement de notre application web -->
<groupId>fr.noubliepaslalistedescourses</groupId>
<artifactId>noubliepaslalistedescourses</artifactId>
<type>war</type>
</deployable>
</deployables>
</configuration>
</configuration>
</plugin>
Chapitre 8
Maven et JEE
135
ces deux rpertoires, il nest pas compliqu de construire ces deux rpertoires
manquants et cest dailleurs ce que propose le plugin war avec sa tche inplace.
mvn war:inplace va prparer lapplication web, prte tre excute sur un serveur
dapplication qui supporte ce mode de fonctionnement. Une modification dans une
page JSP sera alors applique immdiatement, via le mcanisme de recompilation des
JSP qui est intgr tout serveur JEE.
136
Maven en entreprise
Partie II
4. http://mojo.codehaus.org/sysdeo-tomcat-maven-plugin.
5. http://code.google.com/p/loof/.
Chapitre 8
Maven et JEE
137
Plus dexcuses pour ne pas dvelopper une couverture de test de qualit autour de nos
composants mtier !
Ce dernier exemple montre quil ne faut pas tout attendre des plugins Maven, et que de
nombreux outils fournissent des moyens de tester notre code dans des conditions
confortables directement depuis nos tests jUnit. Le dploiement sur un serveur, mme
pilot par Cargo, reste une opration lourde que nous rservons aux tests fonctionnels
ou aux tests de charge.
JEE6
Venu nous passer un petit bonjour, Antonio samuse bien en voyant notre
configuration Maven pour construire cette belle archive dentreprise EAR qui
nous a cot tant defforts. Pourquoi ce sourire moqueur ? Antonio travaille
138
Maven en entreprise
Partie II
de son ct sur une application JEE6, et les volutions lies cette version de la norme
font de notre construction trois modules (EJB + WAR + EAR) un amusant pachyderme en voie de disparition.
Dans sa sixime dition majeure, la norme JEE fait peau neuve. Aiguillonn par les
solutions alternatives plus lgres proposes par des outils open-source, et en particulier par le succs massif de SpringFramework, le groupe dexperts qui dfinit cette
norme a donn une nouvelle impulsion qui influe fortement sur la faon de dvelopper
pour la plateforme JEE.
Parmi les nombreuses nouveauts introduites pour simplifier le dveloppement, allger
la construction dune application ou dfinir des comportements par dfaut qui vitent
une longue phase de configuration, lassemblage dune application JEE a t fortement
revu.
Les EJB nouvelle mouture ne doivent plus ncessairement tre placs dans une archive
JAR ddie, puis groups dans un EAR avec lapplication web WAR. Ce jeu de poupes
gigognes peut laisser place une simple archive WAR dans laquelle sont placs les
EJB, dont les annotations suffisent dfinir le comportement vis--vis du conteneur. Le
descripteur de dploiement ejb-jar.xml, devenu optionnel, peut tre plac directement
sous WEB-INF.
Les nouveauts de JEE6 vont bien au-del de ces quelques assouplissements dassemblage, mais, au niveau de la construction du projet, cest ce qui a le plus dimpact. Nous
pouvons conserver notre code mtier dans un module spar par souci de clarification
du projet, mais nous navons plus besoin de dfinir un module juste pour construire une
archive EAR. Nous pouvons aussi dployer notre application sur un serveur GlassFish
(qui est limplmentation de rfrence de la norme JEE6) sans avoir besoin dassembler
notre WAR: il nous suffit de configurer le mode inplace sur notre application web et de
lancer le serveur. Notre EJB bnficie dun serveur JEE complet, y compris la gestion
du cycle de vie, lenrobage transactionnel ou encore la persistance JPA.
Nous pouvons mme faire encore mieux en exploitant le plugin Maven pour GlassFish6, qui propose un mode de fonctionnement quivalent ce que nous avons vu pour
Jetty. Il suffit de lancer une simple commande Maven pour que le serveur soit tlcharg et quil dmarre en embarquant notre application telle quelle est dans notre
IDE, sans assemblage dun WAR ou autre perte de temps.
6. https://maven-glassfish-plugin.dev.java.net/.
Chapitre 8
Maven et JEE
139
Conclusion
La norme JEE peut paratre complexe, encombre de descripteurs XML et darchives
imbriques. Maven permet dune part de prendre en charge de manire transparente ses
particularits, mais surtout dintgrer un ensemble de bonnes pratiques et doutils qui
simplifient les dveloppements ou amliorent la productivit.
Une fois de plus, Maven ne fait que catalyser, grce une srie de plugins officiels ou
externes, les bonnes ides de dveloppeurs du monde entier. Lintgration en quelques
lignes de XML des meilleurs outils du moment est pour lutilisateur final un confort
sans prcdent.
9
Maven et les IDE
Nous avons jusquici considr Maven comme un outil en ligne de commande. Le
dveloppement informatique est cependant depuis longtemps assist par des environnements intgrs toujours plus volus (et gourmands). Ladoption de Maven sur de
nombreux projets pose donc le problme de sa bonne intgration dans nos outils
de travail.
Rgulirement, nous voyons arriver de nouveaux dveloppeurs en renfort ponctuel.
Nous qui sommes plutt rceptifs aux concepts Maven, nous sommes confronts
chaque fois au rejet de cet outil en ligne de commande et de ses messages parfois
obscurs. Nous devons donc dfinir de manire plus pragmatique notre environnement
de dveloppement pour fournir un ensemble intgr et adapt aux attentes des dveloppeurs.
Un plugin Maven pour Eclipse
Arnaud a dans un premier temps tent de dvelopper un plugin Maven ddi la
configuration dEclipse, lIDE le plus couramment utilis par les dveloppeurs.
Lide est dextraire du fichier POM toutes les informations ncessaires pour
configurer lenvironnement Eclipse, ses nombreuses fonctionnalits et extensions.
Le format des fichiers de configuration de lIDE ntant pas trs complexe, Arnaud
arrive assez vite un rsultat fonctionnel. Lengouement des quipes permet damliorer
les fonctionnalits grande vitesse, mais rapidement Arnaud croule sous les demandes
parfois contradictoires.
Nicolas utilise lenvironnement de programmation par Aspect AJDT. Lintgration dAspectJ sous Eclipse quil propose en fait un outil puissant.
Arnaud ajoute les options et paramtres ncessaires au plugin pour crer les
142
Maven en entreprise
Partie II
Ce ntait, semble-t-il pas, une si bonne ide de tout miser sur AJDT. Un magnifique
hack permet de contourner le problme en paramtrant le plugin avec ajdtVersion=none, afin de dsactiver artificiellement la prise en compte dAJDT dans le plugin
eclipse. Le problme est certes corrig, mais la solution est loin dtre satisfaisante !
Sans parler de la faon dont nous allons devoir expliquer a dans la documentation du
plugin sans passer pour des sagouins.
Certains rclament le support du plugin Eclipse Machin Truc Muche, dautres ralisent leurs applications web via les Eclipse Web Tools. Quelques-uns ont install
Easy-Eclipse, une distribution de lIDE intgrant une slection de plugins, alors
que les plus exigeants prfrent slectionner eux-mmes la composition de leur
environnement. Sans oublier les fans (ou victimes) dIBM qui ne jurent que par
RAD !
Assez rapidement, laffluence des demandes dpasse la capacit dArnaud tablir une
liste de priorits et surtout puise sa bonne volont. Eclipse nest pas proprement
parler un IDE mais plutt une plateforme drive en presque autant de variantes quil y
a de dveloppeurs. Malgr ses efforts, la configuration dEclipse reste incomplte et
ncessite encore et toujours soit des manipulations complmentaires dans lIDE, soit
lajout de blocs entiers de configuration dans notre POM qui seront copis tels quels
dans lenvironnement de travail. Solution peu satisfaisante !
Maven vu depuis lIDE
Loin de se dcourager, Arnaud trouve encore du temps libre pour se lancer dans
lvaluation de la solution inverse : faire confiance lIDE pour analyser le fichier
POM de Maven. Pour ne pas le laisser seul dans cette lourde tche ou peut-tre par
peur quil nous impose son point de vue , nous organisons un concours interne :
Eclipse vs NetBeans vs Intellij Idea.
Chacun de ces environnements sera dfendu par son "cobaye" : Nicolas pour Eclipse,
Raphal pour NetBeans et Stphane pour Idea. Le reste de lquipe jouant le rle du
jury exigeant et impartial. vos marques, prts, cliquez !
Chapitre 9
143
Notre concours repose sur quelques critres pour ne pas fausser le jeu :
m
fonctionnalits bonus.
Eclipse
Notre premier candidat na pas eu la tche facile, puisque ce nest pas une
mais deux solutions quil a d prsenter un jury plutt dubitatif : la fondation Eclipse a accept deux contributions concurrentes visant fournir une
intgration de Maven dans lenvironnement de dveloppement ponyme : m2eclipse 1 et
q4e (rebaptis pour loccasion IAM2).
Ces deux contributions sont cependant relativement comparables et destines fusionner au sein de lincubateur de la fondation Eclipse dans le meilleur des cas, la survie
dun seul des deux candidats est plus probable. Nicolas sest donc focalis sur
m2eclipse (en version 0.9.8), qui propose rgulirement de nouvelles versions, sachant
que des fonctionnalits quivalentes sont disponibles ou planifies chez son concurrent
avec une prsentation un peu diffrente. Le seul hic de ces plugins est quils alourdissent
considrablement lenvironnement de dveloppement Eclipse
Installation
Comme tout composant dEclipse, le support de Maven passe par linstallation de
plugins. Le mcanisme de sites dinstallation et de mise jour permet deffectuer
lopration en quelques clics partir dune connexion Internet. Un redmarrage est
prfrable pour terminer linstallation.
Import dun projet Maven
Limport dun projet Maven commence par un simple clic droit, qui lance un assistant.
Lutilisateur indique le chemin du projet, et le plugin analyse le fichier POM, identifie correctement les rpertoires de code source, ainsi que ceux associs des gnrateurs de code quil excute automatiquement. Il est galement capable de configurer
1. http://www.eclipse.org/m2e/.
2. http://www.eclipse.org/iam/.
144
Maven en entreprise
Partie II
Lutilisation courante de Maven est totalement enrobe dans des assistants et la ligne de
commande nest plus du tout ncessaire. Maven est automatiquement invoqu lors des
rafrachissements de lenvironnement de travail, permettant ainsi dexcuter les tches
associes aux plugins en complment de la compilation Java par lIDE. Les deux environnements se compltent donc, Eclipse ne conservant sa charge que la compilation
des sources Java.
Chapitre 9
145
Figure 9.1
Un projet Maven vu sous Eclipse au travers de m2eclipse.
Gestion du POM
Un diteur graphique est propos pour le POM. Il permet de saisir les mtadonnes
sans avoir se soucier de la structure XML sous-jacente. La gestion des dpendances propose une assistance la saisie des identifiants de groupe, dartefact et de
version, base sur un index du dpt de bibliothque mis jour priodiquement en
tche de fond. Un onglet ddi permet de consulter les dpendances du projet et
didentifier le jeu de transitivit travers lequel elles apparaissent dans le projet
(voir Figure 9.2).
Une vue permet dobtenir un graphe des dpendances. Esthtique, ce nest au mieux
quun gadget pour impressionner ses collgues et justifier son statut dexpert Maven.
La vue XML bnficie galement denrichissements par rapport lditeur XML de
base. Elle permet de saisir rapidement les structures rptitives du POM via un patron
type, comme les <dependency> ou les <execution>, ou dinclure la configuration de
quelques plugins rcurrents, comme pour les plugins war ou aspectj. Lutilisateur peut
dailleurs dfinir ses propres patrons pour les plugins ou structures XML quil utilise
rgulirement. Comme dans lditeur graphique, lditeur XML propose une assistance
la saisie pour les identifiants de groupe, dartefact et les versions.
146
Maven en entreprise
Partie II
Figure 9.2
Gestion des dpendances.
La configuration des plugins, qui se fait exclusivement dans la vue XML, est, elle aussi,
assiste : m2eclipse identifie les paramtres des plugins et les propose par compltion
automatique, ce qui vite de devoir consulter la documentation et de faire une malheureuse faute de frappe dans leur nom. La Figure 9.3 montre m2eclipse en action proposant
cette assistance.
Figure 9.3
dition de la configuration des plugins.
Chapitre 9
147
Figure 9.4
Veuillez patienter
148
Maven en entreprise
Partie II
INFO
Mme si lquipe Maven na pas les moyens de faire plier significativement Eclipse ses
usages, elle essaie de traiter ce problme son niveau. Des volutions sur quelques
plugins cls et le noyau de Maven permettent de mieux prendre en charge la compilation
incrmentale dEclipse, en nexcutant que les tches spcifiques de Maven et en laissant
lIDE prendre en charge toutes les tapes pour lesquelles il propose une fonction quivalente.
Et la cerise
Le plugin Maven vient complter les fonctionnalits de correction rapide (Quick Fix)
dEclipse. Lors de lutilisation dune classe non rfrence, dun simple clic droit vous
obtenez une liste de dpendances qui dfinissent la classe considre (voir Figure 9.5).
Il nest donc pas ncessaire de passer par ldition du POM pour ajouter une dpendance suite au copier-coller dun fragment de code intressant.
Figure 9.5
Correction rapide par ajout dune dpendance.
Pour finir sa dmo, Nicolas passe dans la vue dpendances, effectue une recherche sur
commons-logging et obtient au bout de quelques instants une liste de bibliothques
varies et les chemins par lesquels nous rcuprons ce JAR controvers dans notre
projet. Un simple clic droit permet de lexclure en ajoutant les nombreuses exclusions
qui simposent. Ceux dentre nous qui se sont dj battus avec la gestion des dpendances
de Maven, parfois un peu trop gnreuse, apprcient ce raccourci.
Chapitre 9
149
Interrogations
Les versions successives de m2eclipse apportent corrections et nouvelles fonctionnalits et montrent un rel dynamisme pour proposer une intgration fiable et productive
de Maven avec Eclipse. Il reste cependant assez dconcertant de voir deux plugins, dont
larchitecture est relativement incompatible, hbergs par lincubateur de la fondation
Eclipse. Si quelques points de collaboration sont possibles, une fusion pure est simple
nest pas envisageable. Que va-t-il en ressortir, et surtout quelle chance ?
Intellij Idea
Notre deuxime candidat utilise lenvironnement de dveloppement de
JetBrains, Intellij Idea. Outil propritaire et payant, Idea part avec un
handicap par rapport ses concurrents pour notre jury, grand fan des logiciels libres. Stphane a prvu le coup et nous informe quIdea est offert aux dveloppeurs de projets open-source reconnus ainsi quen lot pour les Java User Group.
Il a ainsi pu sen procurer une licence sans trop deffort, sachant quon peut aussi
tenter laventure avec une version dvaluation. Le prix dbourser pour une licence
nexcde de toute faon pas quelques centaines deuros, comparer au prix de la
journe dun consultant.
Import dun projet Maven
Idea tant, comme tous les IDE rcents, bas sur des mcanismes dextensions, il nous
faut dabord installer le plugin Maven. Cette formalit rgle, il ne nous reste qu
demander limport de notre projet en indiquant son rpertoire racine (ou son URL
Subversion), et fournir quelques paramtres de base comme le JDK utiliser et les
profils Maven activer dans notre environnement. On laisse ensuite lIDE analyser et
indexer tous les lments du projet et de ses dpendances. Cette phase dimport peut
tre assez longue et nous permet de dcouvrir un premier lot dastuces dIdea, ou
encore de vrifier le bon fonctionnement de la machine caf.
Aprs cette premire tape incontournable, Idea prsente chaque module du projet
comme un projet Java, en ayant identifi les rpertoires de code gnr, le niveau de
langage utiliser pour la syntaxe Java et lensemble des dpendances. Comme sous
m2eclipse, Les rfrences inter-modules sont dfinies comme telles (sans passer par
larchive JAR), ce qui nous permettra dditer librement les sources des diffrents
modules et de constater immdiatement leur impact.
Jusquici, notre projet Maven est donc parfaitement bien pris en charge par lenvironnement de dveloppement (voir Figure 9.6). Nos modules sont clairement identifis et
150
Maven en entreprise
Partie II
prsents dans une vue ddie. Celle-ci nous permettra de lancer depuis lIDE les
oprations gres par Maven, par exemple une construction jusqu une phase prcise
du cycle de vie ou lexcution dun plugin particulier.
Figure 9.6
Le projet Maven aprs import dans Idea.
Gestion du POM
Ldition du fichier POM se fait via sa reprsentation XML, avec cependant de
nombreux assistants. Idea identifie, par exemple, toutes les dpendances qui ne sont
pas compatibles OSGi et propose de rechercher pour une version OSGi-ready, dans un
dpt spcialis (typiquement celui gr par SpringSource pour son DM server). Bien sr,
tous ceux qui ne ciblent pas un environnement de ce type ny verront quun gadget, mais
lengouement rcent pour cette plateforme modulaire nest pas ngliger ; aussi, est-il
intressant de constater que nos outils sont dj niveau pour la grer.
Au sein de lditeur XML, Idea propose une assistance la saisie ddie Maven, par
exemple pour saisir les identifiants dune dpendance ou dun plugin. Ces rfrences agissent comme des hyperliens et permettent de naviguer dans les POM du projet de manire
fluide. Idea ne propose cependant aucune vue graphique des mtadonnes Maven. Pas de
synthse ni doutil danalyse des dpendances. On reste donc un peu sur sa faim.
La vue de configuration du module (au sens Idea du terme) reflte cependant parfaitement les mtadonnes de notre projet Maven (voir Figure 9.7). On y retrouve tous
nos rpertoires de code source (et de code gnr), que nous pouvons au besoin
complter, mais dans ce cas la configuration Idea ne sera plus synchrone avec le
projet Maven.
De la mme faon, les dpendances du projet sont clairement identifies, avec un
petit raffinement propre Idea qui diffrencie le code de test du code principal,
ainsi que les bibliothques qui sont spares en deux catgories (voir Figure 9.8).
Chapitre 9
151
Figure 9.7
La configuration du module Idea partir des mtadonnes Maven.
Les bibliothques non exportes ne seront pas visibles depuis un autre projet qui fait
rfrence au module considr. Pas de risque ainsi dintroduire involontairement des
imports parasites.
Figure 9.8
Les dpendances Maven vues sous Idea.
152
Maven en entreprise
Partie II
Chapitre 9
153
Avant que le dbat ne senlise dans de striles discussions sur le temps ncessaire pour
apprivoiser un nouvel environnement et sur la compensation que peut apporter un outil
plus efficace, nous dcidons de passer notre troisime candidat.
NetBeans
Notre dernier candidat est un farouche partisan de NetBeans et compte bien
nous dmontrer sa supriorit pour le mariage de Maven avec un environnement de dveloppement intgr.
Prise en main
Le support de Maven est nativement intgr dans NetBeans, nous navons donc aucun
plugin installer. Cest prometteur : les dveloppeurs de NetBeans ont pris bras-lecorps la problmatique du support de Maven dans lIDE et nont pas dlgu une
quipe externe lintgration de cette fonctionnalit. Le reste de lenvironnement na
rien de fondamenta-lement dconcertant et la visite guide propose par Raphal
neffraie pas grand monde.
Import dun projet Maven
Seconde bonne surprise, que Raphal ne manque pas de souligner, NetBeans
nimporte pas un projet Maven, il se contente de lire nativement le POM. Autrement
dit, NetBeans ne va pas chercher traduire le POM pour crer sa propre configuration
comme le font Eclipse ou Idea, mais il va entirement se baser sur le POM. Nous
sommes ainsi assurs que les modifications qui lui seront apportes seront prises en
compte sans ncessiter une quelconque synchronisation, de mme que nous ne
risquons pas de tomber dans le travers de modifier la configuration de lIDE sans que
le POM soit cohrent. La Figure 9.9 montre limport dun projet Maven, et, comme le
souligne avec insistance Raphal, le POM nest pas dans cet environnement un
format annexe, mais bien un descripteur de projet part entire qui se suffit compltement.
Nos dpendances, rpertoires de sources (y compris le code gnr) et sous-modules
sont parfaitement dtects, NetBeans ayant mme le bon got de sparer nos dpendances de test, ce qui amliore la lisibilit du projet qui compte plusieurs dizaines de
bibliothques. Le lancement dune construction du projet dans lIDE excute tout naturellement Maven dans une console, et nous pouvons videmment excuter la demande
une tche particulire.
154
Maven en entreprise
Partie II
Figure 9.9
Ouverture native dun projet Maven.
Gestion du POM
Ldition des mtadonnes du POM se fait ici aussi selon le formalisme XML. lintrieur de cet diteur, NetBeans ne propose pas dassistance la saisie spcifique de
Maven. Par contre, nous pouvons introduire de nouvelles dpendances via un menu
contextuel (clic droit sur licne qui regroupe nos bibliothques). Lassistant propose
alors un outil de recherche, bas, comme ses concurrents, sur les index mis disposition
par les gestionnaires de dpts.
Intgration des plugins Maven
NetBeans ne propose pas dintgration particulire des plugins Maven pour lesquels il
dispose de plugins quivalents. Cette passerelle semble donc tre une spcificit
dEclipse, que certains apprcieront mais laquelle dautres, comme Raphal, prfreront un environnement rellement fonctionnel. Une rapide dmonstration de dveloppement suffit dailleurs le prouver, et Raphal rejoint ainsi Stphane dans son
combat tout sauf Eclipse.
Bonus
NetBeans prend en charge la gestion des bibliothques Maven de manire particulirement intgre dans les rouages de lIDE. Les assistants de correction (Quick Fix)
proposent par exemple de corriger un import non rsolu en ajoutant la dpendance
Chapitre 9
155
adquate, via une recherche dans le dpt. Comme lindique la Figure 9.10, Raphal ne
se prive pas de nous montrer cette fonctionnalit comme preuve de la premire place
quoccupe Maven dans son environnement prfr.
Figure 9.10
Intgration de la gestion des dpendances au plus profond de NetBeans.
Dlibration du jury
La dlibration du jury est longue et mouvemente. Riche en arguments, en comparaisons mais aussi parfois en mauvaise foi, la discussion se prolonge sans fin et le rsultat
ne coule pas de source. Chacun y va de sa petite dmo, de sa fonctionnalit absolument
indispensable que lautre na pas, de ses considrations sur la formation des dveloppeurs La conclusion finit par merger, avec laide dun regard externe au dbat.
Venu nous rendre une petite visite de courtoisie, Sbastien stonne de nous
trouver dans cette situation de guerre de chapelles. Pour dbloquer la situation, il lui suffit de poser une question toute bte : "Mais est-ce que vous
pouvez toujours construire le projet 100 % en ligne de commande ?" Bien sr que oui,
environnement de dveloppement intgr ou pas, notre projet repose entirement sur
Maven et ne dpend daucun des trois IDE candidats lintronisation.
Dans ce cas, en quoi est-ce important ? Si Stphane est laise sous Idea, Raphal indcrochable de son NetBeans, et Nicolas tellement profondment habitu Eclipse quil
ne sait plus sen passer, pourquoi les faire changer ? Chacun trouve son compte dans
son environnement, le tout est que la construction du projet ne soit pas affecte par les
choix locaux de chacun. Aprs tout, il na jamais t question de demande Arnaud de
renoncer son Mac, tout simplement parce que cela na aucune influence sur le projet,
de mme que Raphal travaille sous Linux.
156
Maven en entreprise
Partie II
Conclusion
Un norme avantage de Maven est quil porte intgralement le projet. Que lon travaille
dans un environnement graphique ou avec le bloc-notes na aucune influence sur le
projet lui-mme. Seul lutilisateur peut tre pnalis par un environnement quil ne
matrise pas, aussi autant le laisser choisir librement. Ne forcez pas un utilisateur dIdea
sur Mac supporter avec angoisse un Eclipse sous Windows. Nobligez par un
"linuxien" sous NetBeans abandonner ses raccourcis prfrs. Ne demandez pas
un habitu du couple Windows/Eclipse comme il en existe des milliers tout rapprendre juste pour rpondre un choix venu den haut, avec la perte de productivit qui va
ncessairement en dcouler.
Maven nous a librs des IDE, nous pouvons utiliser celui que nous voulons et en changer
tout moment, car aucune de nos tches stratgiques ny est lie.
10
Le jour J : la livraison
La vie dun projet est ponctue de moments forts, et le jour de la livraison en est un
particulirement prouvant. Aprs de longues semaines de dveloppement et de
mise au point, notre logiciel est mis la disposition de ses utilisateurs, soumis
leur jugement et leur manque de compassion pour les erreurs que nous aurions pu
commettre.
Stratgie de livraison
Premire livraison
La toute premire version publique de noubliepaslalistedescourses a t
particulirement hroque. Tout commence par plusieurs semaines de tests
intensifs pour identifier tous les bogues qui auraient pu nous chapper. Les
derniers correctifs sont appliqus, avant de se lancer dans une ultime journe de vrification pour tre sr de ne rien laisser au hasard. Aprs quoi, il nous faut prparer le logiciel enfin stabilis et valid pour la diffusion. Emmanuel prend en charge la prparation
de cette toute premire mouture.
Il commence par parcourir tous les fichiers de configuration du projet pour indiquer
comme numro de version la fameuse valeur 1.0.0. Le projet, reconstruit avec cette
nouvelle configuration, est test une dernire fois avant dtre rendu public. Emmanuel
marque dans notre gestionnaire de code source ce moment crucial, ce qui se traduit par
la pose dun "tag". La journe se termine donc tard autour dune bonne bouteille pour
fter le succs de notre belle aventure. noubliepaslalistedescourses est dsormais en
ligne et attend de pied ferme ses utilisateurs.
158
Maven en entreprise
Partie II
Deuxime livraison
Une mauvaise surprise nous tombe dessus lorsque nous devons en urgence appliquer
une correction pour un problme de performances. Soumise un succs inattendu,
lapplication a commenc cafouiller et il a fallu trouver des palliatifs immdiats.
Le tag pos par Emmanuel nous permet de rcuprer le code source associ cette
fameuse version 1.0.0 et de prparer aussi vite que possible une version 1.0.1 corrigeant
ce problme. Et l, impossible de reconstruire le projet. Lors de la premire livraison,
les modifications navaient pas t compltement intgres dans le gestionnaire de code
source lors de la pose du tag. Emmanuel doit donc grer dans lurgence deux problmes
l o un seul lui suffisait dj largement.
Pour ne pas reproduire la mme erreur, il dcide de poser le tag de la version 1.0.1, puis
dextraire du gestionnaire de sources le code associ au tag encore tout frais et de sen
servir pour construire le logiciel qui sera valid une toute dernire fois avant dtre
publi. Si jamais nous dtections un problme de dernire minute, il nous suffirait
dapporter les corrections ncessaires, de poser un nouveau tag et de reprendre la procdure.
Troisime livraison
Les choses semblent enfin matrises, mais nous dchantons vite quand dautres problmes apparaissent sur la version 1.0.1. Aprs analyse, on comprend que ces problmes
auraient d tre dtects par notre outillage de tests. Alors, que sest-il pass ?
Ces tests sont malheureusement associs un profil qui doit tre activ la demande.
Comme ils portent sur les accs la base de donnes, et pour ne pas pnaliser les autres
dveloppeurs, nous les avons isols dans un profil ddi, comme nous lavons vu au
Chapitre 4. tait-ce une fausse bonne ide ?
Lquipe de dveloppement, malgr le fiasco de cette version corrective, nen est pas
convaincue. Les profils permettent chacun dtre correctement outill sur la partie qui
le concerne sans tre handicap par des temps de construction interminables ou par des
prrequis sur lenvironnement de dveloppement.
Lors de la construction de notre projet avant livraison, nous devons tout simplement ne
pas ngliger dactiver tous les profils adquats pour valider au maximum lapplication.
Nous pouvons mme ajouter, cette phase cruciale, des profils spcifiques pour adjoindre des informations dans le livrable : date de livraison, auteur de la livraison, numro
de rvision dans le gestionnaire de code source
La version 1.0.2 sera donc la bonne, maintenant quEmmanuel tient enfin une procdure de livraison fiable et connue de tous ?
Chapitre 10
Le jour J : la livraison
159
Documentation
La procdure peut tre aussi btonne quon le voudra, elle nest fiable que si elle est
applique scrupuleusement. Autrement dit, le facteur humain reste comme toujours
lpe de Damocls qui menace les projets.
La plupart des entreprises rpondent ce problme par une documentation lourdement
contrle, rpondant des rgles trs strictes de contrle qualit et des nomenclatures
prcises. En supposant que tout le monde soit rompu aux pratiques de qualit et vive
dans un monde labellis AFAQ et ISO-900x, cela devrait garantir le succs du projet en
toute circonstance. Seulement, nous ne vivons pas dans ce monde est-ce rellement
regrettable ?
Dautres prfrent une approche plus souple et ractive en faisant appel lauto-organisation, par exemple via une documentation supporte par un wiki.
INFO
Pour ceux qui ne le sauraient pas, un wiki est un site web dont le contenu peut tre modifi,
corrig ou complt par ses utilisateurs. Il est donc trs dynamique et peut sadapter la
ralit des problmes rencontrs et sorganiser en fonction des informations rellement
utiles.
Un wiki nest pas du tout incompatible avec une gestion "classique" de la documentation. Si
vous nen avez pas un sur votre projet, faites un petit essai avec votre quipe, vous serez
surpris du rsultat. Les solutions ne manquent pas, du wiki PHP de base au trs professionnel
Confluence, en passant par lincontournable XWiki cher Vincent.
Emmanuel documente ainsi la procdure de livraison dans notre wiki, accessible rapidement et sans les ambiguts dune classification documentaire complexe. Elle a aussi
lnorme mrite de permettre celui qui applique la procdure de venir complter la
documentation pour prciser un point quil trouve mal expliqu, ou donner des indications sur un point pas assez dtaill. Certains seront trs laise avec les commandes
Unix alors que dautres auront besoin quon les prenne par la main.
Est-ce vraiment la panace ? Pourquoi acceptons-nous que le moment de la
livraison le plus crucial de la vie du projet soit le seul ne pas bnficier
de lapproche que Maven a apporte au projet : lautomatisation aussi
complte que possible via une commande unique. Emmanuel a pris le soin de documenter dans le dtail la procdure, et le principe du wiki permet chacun de la complter si un point restait obscur. Cependant, nous construisons tous nos projets, quelles que
soient leur complexit ou leur technologie, par la commande universelle mvn install.
La procdure de livraison ne pourrait-elle pas elle aussi tre homognise ? Emmanuel
part donc la pche aux bonnes pratiques du ct de Maven et de ses plugins
160
Maven en entreprise
Partie II
Le plugin release
Le plugin release de Maven a t conu dans cet esprit. Il regroupe en une seule
commande toutes les bonnes pratiques de livraison apprises sur de nombreux projets.
En lutilisant, vous naurez pas comme nous apprendre vos dpens que ltablissement dune procdure fiable ne simprovise pas. Surtout, vous naurez pas besoin de
20 pages de documentation pour indiquer la procdure suivre.
Pour vous donner une ide de ce que le plugin propose, voici le processus quil applique
pour produire un livrable.
tape 1 : prparation
m
Il contrle lenvironnement de lutilisateur qui ne doit prsenter aucune modification non sauvegarde dans le gestionnaire de code source. Optionnellement, un
accs exclusif au gestionnaire peut tre demand pour les plus paranoaques dentre
nous.
Il modifie les indications de version dans les fichiers POM des modules du projet.
Le plugin peut tre configur pour affecter la mme version toutes les branches
dun projet multimodule, sinon il demandera de saisir une version pour chacun
deux.
Il effectue une construction complte du projet pour contrler les modifications appliques automatiquement et sassurer quelles nont pas un impact
ngatif.
Il modifie nouveau les indications de version pour pointer vers la version de dveloppement suivante et les sauvegarde.
Comme vous pouvez le constater, la dmarche est plus que rigoureuse et elle est entirement automatise. Au final, le projet dispose, dans son gestionnaire de versions, dun
Chapitre 10
Le jour J : la livraison
161
Le point capital ici est que la description de la configuration et des commandes ncessaires la construction correcte du livrable est entirement documente dans le POM
lui-mme. Pas de document connatre, retrouver dans la bonne version ou ne
surtout pas oublier de mettre jour.
Un projet Maven utilisant le plugin release permet de raliser une livraison totalement
matrise, contrle et synchronise avec le gestionnaire de code source en une simple
commande :
mvn release:prepare release:perform
Emmanuel est plus que satisfait par cette simplicit. Maven prouve ici son efficacit :
une commande unique pour raliser un traitement loin dtre simple et applicable sur
tous nos projets, toutes complexits et technologies confondues. Reprenez le document
PROCx589002-02.1-Procdure de livraison.doc que vous aviez jusquici et servezvous-en pour caler votre armoire bancale. Et si votre responsable qualit vous rclame
un document de procdure, faites-lui une photocopie de la Figure 10.1 !
ASTUCE
Cette procdure est loin dtre lmentaire et il y a donc de nombreuses raisons quelle
plante en cours de route avant dtre compltement au point. Le plugin propose un mode
dryRun qui permet de lexcuter blanc, sans quaucune modification soit applique dans
le gestionnaire de code source, le temps de bien mettre au point la configuration du
plugin.
162
Maven en entreprise
Vrification
quil ny a pas
de changement
local
Partie II
Vrification
quil ny a pas de
dpendances
SNAPSHOT
Modification en
version non
SNAPSHOT dans
le POM
Modification
de lURL du SCM
pour
le tag crer
Compilation du
code et des tests
Excution des
test unitaires
Commit du
changement dans
le POM
Passage la
version
SNAPSHOT
suivante dans le
POM
Commit du
changement
dans le POM
Chekout des
sources tagges
Compilation du
code et des tests
Excution des
tests unitaires
Packaging du
livrable
Dploiement
du livrable sur
le dpt partag
Gnration et
dploiement de
la documentation
et des rapports
release : prepare
release : perform
Figure 10.1
tapes ralises par le plugin release.
Chapitre 10
Le jour J : la livraison
163
Et si a foire ?
La prparation de la livraison comprend de nombreuses tapes et contrles. Si lune
delles choue, le plugin va videmment sinterrompre. Aprs avoir identifi et corrig
le problme, nous avons deux options :
m
Reprendre toute la procdure son point de dpart. Le plugin release propose alors
de faire un retour arrire complet dans ltat initial, dans lesprit de ce que propose
une base de donnes au cours dune transaction :
mvn release:rollback
La seconde solution est videmment moins stricte ; cependant, vous pouvez parfois tre
bloqu par un problme purement local et indpendant de la stabilit du projet, comme
un contrle de votre environnement par le plugin enforcer qui choue, ou la construction qui naboutit pas parce que vous navez pas attribu suffisamment de mmoire
lexcution de Maven.
Dans les deux cas, la rsolution du problme ne ncessite pas de modifier le projet
lui-mme, et le plugin release permet de reprendre le processus : par dfaut, lanc
une deuxime fois sur le mme projet, il va reprendre sa tche l o il en tait rest,
sauf si on lui indique explicitement de tout reprendre de zro via loption -Dresume=false.
Notre prochaine version
La livraison de la version 1.2.0 de noubliepaslalistedescourses na pas t une de ces
journes de stress sans fin, qui se terminent bien aprs le coucher du soleil. Elle na pas
non plus t mene par un expert rompu tous nos outils et spcialiste de la procdure.
Cest notre stagiaire qui la ralise, le plus naturellement du monde, et sans mme se
rendre compte de ce quavaient pu tre les livraisons prcdentes.
Lapproche par convention et lexcellente extensibilit de Maven montrent toute la
force de celui-ci dans le plugin release. Un seul fichier, utilisant un formalisme XML
certes verbeux mais simple, permet de dcrire toutes les tapes de construction et toutes
les options ncessaires pour obtenir un rsultat fiable.
164
Maven en entreprise
Partie II
travers du processus de livraison. Aussi, nous voulons tester une dernire fois avant de
mettre le coup de tampon "bon pour le service".
Cest nouveau Emmanuel qui sy colle, maintenant quil est devenu notre
gourou de la livraison. Pour notre version 1.3.0, il propose de complter
notre procdure techniquement bien rode dune phase supplmentaire de
tests. La version marque 1.3.0 sera installe sur notre serveur de validation et subira
nos tests les plus redoutables. Comment grer cependant les versions dans les essais
successifs que nous allons probablement enchaner ? Chaque candidat au titre de livraison
officielle a sa propre identit et ne doit pas tre confondu avec les autres.
Premire option, utiliser un nombre supplmentaire dans le numro de version, indiquant le numro du candidat dans la course au logiciel sans faille. La 1.3.0.1 sera probablement imparfaite, la 1.3.0.2 aura son lot de rgressions inacceptables, la 1.3.0.3 sera
peut-tre la bonne. Certains logiciels suivent cette option et ne diffusent publiquement
que les sous-versions qui ont satisfait tous les critres de qualit. Les utilisateurs
peuvent cependant tre surpris de constater des manques dans la srie des numros de
version.
Emmanuel naime pas trop cette solution et voudrait pouvoir redfinir la version de
notre meilleur candidat en "1.3.0". Seulement, le code marqu dans notre gestionnaire
de code source ne porterait pas la bonne version, et le tag serait inadapt. Une fois de
plus, Maven et son plugin release viennent notre secours. Lorsque nous excutons la
commande mvn release:perform, nous demandons Maven de construire le livrable
et de le diffuser sur notre dpt public. Une autre commande mvn release:stage est
trs comparable mais remplace automatiquement la phase de dploiement pour pointer
sur notre dpt de validation. Le logiciel install sur celui-ci sera donc strictement identique, au bit prs, une livraison classique mais aura juste chang de destination. Nous
pourrons donc le tester attentivement en toute tranquillit.
La seconde diffrence quintroduit stage est quil conserve la possibilit de lancer un
rollback. Il est donc possible, si la version en cours de test ne nous satisfait pas, de
revenir en arrire sur notre gestion de version et de relancer plus tard une nouvelle
version avec le mme numro de version.
Si effectivement notre premier "release candidate" est insuffisant pour rpondre nos
exigences, il nous suffit de revenir via un release:rollback en version 1.3.0-SNAPSHOT. La seule chose qui restera du candidat malheureux est le tag, que nous pouvons
renommer en 1.3.0-RC1. Si, par malheur, toutes nos tentatives ne produisaient quun
logiciel encore pire, nous pourrions toujours, presss par le temps, repartir de ce tag.
Celui-ci prsente bien la capacit de produire un projet en version 1.3.0 !
Chapitre 10
Le jour J : la livraison
165
Carlos est trs intrigu par les explications dEmmanuel sur cette procdure
de mise sur tagre dune version candidate. Il propose alors dutiliser un
autre mcanisme, en se fondant sur le gestionnaire de dpt dont il a la
responsabilit. Notre procdure de livraison va produire un livrable dans la version
cible 1.3.0 et le diffuser sur le gestionnaire de dpt. Par contre, lemplacement dans
ce dpt sera choisi dans une sous-catgorie spciale, ddie aux prversions candidates. Nos bta-testeurs pourront pointer dessus pour rcuprer le binaire et le tester en
connaissance de cause, alors que les autres utilisateurs nen auront pas connaissance.
Une fois cet artefact valid, il suffira de demander au gestionnaire de dpt de le
promouvoir dans le dpt public (sous Nexus, dans la version pro, voir la gestion des
staging repositories).
Emmanuel et Carlos nous proposent ainsi, par le biais doutils propres au monde
Maven, une procdure complte, fiabilise et totalement automatise pour produire
notre livrable, le tester puis le diffuser.
Urgence !
Notre version 1.3.0 nest pas encore compltement stabilise que nous avons un
retour alarmant dun de nos clients sur la version 1.2.0. Un bogue trs gnant, qui
ncessite de notre part une intervention immdiate. Impossible de proposer une
migration dans la nouvelle version qui nest mme pas encore prte et apporte de
toute faon des changements significatifs dont notre client na que faire dans son tat
desprit du moment.
Il nous faut un correctif, une 1.2.1, et le plus vite sera le mieux. Et cest bien sr sur
Emmanuel que a tombe une fois de plus !
Mais, cette fois, Emmanuel ne sest pas laiss prendre de vitesse et a prvu
le coup. Notre gestionnaire de code source prend ce problme en charge
travers la notion de branche. En parallle, vont commencer crotre dun
ct le tronc du projet, correspondant la version 1.3.0 qui continue son chemin, et,
dun autre ct, une branche 1.2.1, dont le point de dpart est le moment exact de cration de la version 1.2.0. Les divergences entre les codes de ces deux versions pourront
tre fusionnes plus tard, ou peut-tre resteront-elles dfinitivement spares, lavenir
nous le dira. La Figure 10.2 donne une ide de la gestion en parallle de versions, avec
un point de branchement et un point de fusion quelques semaines plus tard. Cette
approche peut tre utilise pour des besoins correctifs ou pour exprimenter labri
dun petit coin tranquille une volution complexe, qui impacterait trop le reste de
lquipe.
166
Maven en entreprise
Partie II
Version 2 patch 1
Version 2
Patch 1
Report des
corrections
Trunk
Version 3
Figure 10.2
Utilisation dune branche de dveloppement parallle.
Encore une fois, le plugin release va nous faciliter la tche, ce qui est la moindre des
choses lorsquil faut en plus grer lnervement de notre client au bout du fil et lui prouver notre ractivit. mvn release:branch nous permet de crer rapidement une branche
de dveloppement, avec mise jour de nos POM pour indiquer la version corrective et
les rfrences adquates notre gestionnaire de code source. Nous pouvons alors
commencer travailler dans la branche frachement cre sans perdre de temps.
Il faudra juste configurer le serveur dintgration continue pour scruter lavancement de
ce dveloppement parallle. Sous Hudson, nous pouvons simplement copier la configuration existante pour crer un nouveau job. Seul lemplacement du gestionnaire de code
source sera modifi.
Une fois notre dveloppement termin, le couple release:prepare release:perform
reprendra du service pour produire ce livrable correctif trs attendu. Une fois de plus,
toute cette procdure aurait pu tre traite manuellement, dans une ambiance de stress
et de prcipitation dont les rsultats peuvent tre dsastreux. Maven propose de les
prendre en charge de manire totalement structure et automatise.
Chapitre 10
Le jour J : la livraison
167
DVD
ROM
CDRROMW
HD
Power
Build
Local
Dploiement
Gestionnaire
de sources
DVD
ROM
CDRROMW
HD
Power
Build
Local
Plateforme de
tests fonctionnels
Serveur(s)
dintgration
continue
Publication des
packages
Dpt dentreprise
Plateforme de
recette
Dploiement
automatis par
la production
(anthillpro, script,)
Plateforme de
production
Figure 10.3
Production continue.
Le concept est au final relativement simple. Nous disposons dune automatisation capable de construire, tester en profondeur et publier les versions stables de notre logiciel,
avec toute la rigueur et la traabilit dont peut rver nimporte quel ingnieur qualit.
La seule tape qui reste encore plus ou moins alatoire est linstallation sur nos plateformes de recette puis de production. Pourtant, comme nous lavons vu au Chapitre 8,
Maven assist de Cargo est tout fait capable de dployer nos applications JEE sur
un serveur.
En production continue, nous allons ajouter dans la description du projet (dans notre
POM), ces tapes recette et de mise en production. Il ne restera donc entre le dveloppeur, qui saisit son code, et ladministrateur, qui installe la nouvelle version, aucune
inconnue plus ou moins bien documente. Bien sr, nous devrons aussi intgrer dans le
processus la gestion des migrations de donnes, la possibilit dun retour arrire, mais
ce nest aprs tout quun problme dautomatisation dun processus que nous grions
jusquici la main.
168
Maven en entreprise
Partie II
Emmanuel est plus que satisfait et raconte avec un sourire nostalgique nos
stagiaires les journes rocambolesques des premires versions.
Conclusion
Lautomatisation des processus de dveloppement est une tche qui ncessite un gros
effort initial, non seulement pour dpasser les contraintes techniques mais surtout pour
faire passer les mauvaises habitudes et inculquer une nouvelle vision. Nesprez pas
crer en quelques jours une usine logicielle mettant en uvre des tests unitaires, dintgration et fonctionnels sur une grille de machines. Commencez petit sur des projets
pilotes, essuyez les pltres de vos premires erreurs et attendez un peu pour rcolter les
fruits dun processus enfin compris et dont les utilisateurs seront les meilleurs vanglistes.
La livraison fait partie de ces tapes qui concernent tout le monde avec un haut niveau
de stress. Lautomatisation y prend toute sa force et dmontre son intrt. Maven peut
vous apporter de nombreux services, structurer votre projet, mais cest certainement sur
un point aussi stratgique quil simposera comme outil incontournable. Chaque spcificit de votre projet tant automatise, documente et historise via votre fichier POM,
vous pourrez enfin vous focaliser sur la seule chose qui compte vraiment : le fonctionnement de votre application.
Partie 3
Encore plus loin avec Maven
Linformatique dentreprise ne se limite pas une utilisation raisonne et flexible des
"ressources". Elle doit aussi faire face des contraintes qui viennent den haut, et
auxquelles le projet doit se plier, quelles que soient ses habitudes.
Aprs quelque temps de fonctionnement, notre start-up a atteint un joli succs. Les
promesses de stock-options commencent nous titiller, quand la nouvelle tombe : nous
avons t contacts par le groupe Geegol pour venir complter son offre de services.
Cest une reconnaissance inespre pour notre travail, et nous prparons avec un
mlange denthousiasme et danxit le passage du statut de start-up celui de filiale
dun gant international.
11
Utiliser un outil non support
Jusquici, nous avons toujours trouv pour chaque problme que nous avons rencontr
un plugin Maven adapt. Le "mariage" de notre projet avec les rgles du groupe Geegol
va cependant nous obliger faire quelques efforts supplmentaires.
Un outil maison
Le groupe utilise (pour des raisons que nous naborderons pas ici) un serveur quil a
dvelopp lui-mme, le "Geegol Execution Architecture" GEA pour les intimes. Il
ne sagit pas dun serveur JEE traditionnel, bien quil y ressemble beaucoup et
propose des API de programmation compatibles. Il prsente cependant quelques
restrictions spcifiques quil est ncessaire de respecter pour le bon fonctionnement
de lapplication.
Pour sassurer que ces contraintes sont respectes, plutt que dattendre les phases de
validation du projet et un ventuel crash, le groupe a dvelopp un outil ddi qui identifie ds la conception du code le non-respect de ces rgles.
172
Partie III
Notre projet, venant du monde extrieur, a d passer par cette moulinette pour identifier les adaptations ncessaires, et la tche de mise niveau na pas t aise.
Aussi, nous voudrions viter de replonger dans cette phase de reprise du code et
intgrer ce contrle au plus tt, cest--dire chaque nouvelle ligne de code ajoute
au logiciel.
Inutile de rechercher sur Internet, nous ne trouverons pas de plugin Maven tout prt
pour ce besoin spcifique. Nous sommes le premier projet du groupe utiliser Maven,
aussi il va falloir nous remonter les manches.
Rutiliser lexistant
Loutil de Geegol est assez simple dutilisation. Il est crit en Java, et on
linvoque depuis la ligne de commande en fournissant la liste des fichiers
sources .java analyser. Il faut galement que le classpath soit configur
pour inclure toutes les bibliothques rfrences dans ce code source. Herv sattaque
donc lapplication de ce nouvel outil sur notre projet, en lintgrant dans notre processus
de construction par Maven.
Une tape pralable toute solution base sur Maven est de mettre la disposition de
celui-cila bibliothque de notre outil gea-check sous forme dartefact Maven. Nous
devons donc le placer dans notre dpt de bibliothques, accompagn dun fichier POM
fournissant les mtadonnes adquates, en particulier la liste prcise de ses dpendances. Nous avons dj voqu au Chapitre 2 lidentification des bibliothques et de leur
version. Herv prpare soigneusement un fichier POM et le tlcharge avec larchive
JAR dans notre dpt de bibliothques.
De nombreux projets utilisent Ant pour leur construction ou lont utilis avant de
passer Maven avec les limites que nous avons dj vues. Le groupe a dvelopp
pour son outil une tche Ant qui lance la gnration documentaire, nous ne partons
donc pas de rien.
La solution la plus rapide consiste utiliser la tche Ant telle quelle dans notre
projet Maven. Herv pourra ainsi rassurer tout le monde en prouvant que le choix de
Maven ne met pas des btons dans les roues. Cela est possible grce un plugin standard : antrun, lequel, comme son nom le suggre, va excuter un script Ant lors de la
construction du projet par Maven. Voil qui pourrait bien nous sauver la mise ! Le
Listing 11.1 montre la configuration que nous avons ajoute au projet pour grer cette
tape.
Chapitre 11
173
Ce fragment de script Ant rutilise des variables Maven pour pointer vers les rpertoires du projet, conformment aux conventions de Maven, et manipuler les listes de
dpendances du projet et du plugin. Par dfaut, le plugin AntRun ne propose dans le
ClassPath dexcution du fragment de script que la bibliothque Ant standard (la
version dAnt utilise par dfaut dpend de la version du plugin, Antrun 1.3 utilise
par exemple Ant 1.7.1). Pour invoquer notre tche spcifique, nous devons y ajouter
la bibliothque maison GEACheck (et ses dpendances) via un bloc <dependency>,
appliqu au plugin.
Cette petite manipulation nous permet donc dutiliser sans souci les outils en place. Fin
du Chapitre 11 ? Non, bien sr.
174
Partie III
INFO
Dans le Listing 11.1, nous navons pas indiqu didentifiant de groupe pour dclarer le
plugin. Maven utilise en effet une liste de groupes pour identifier les plugins lorsque cette
information nest pas fournie. Par dfaut, cette liste inclut org.apache.maven.plugins et
org.codehaus.mojo, soit les deux sources officielles de plugins de la communaut des dveloppeurs Maven. Cette liste peut tre enrichie de nouvelles entres (via leur identifiant de
groupe) dans le fichier de configuration de Maven : settings.xml. Si votre entreprise utilise
de nombreux plugins maison, ce mcanisme peut vous aider allger votre configuration,
cependant cela suppose que chaque dveloppeur dispose dun fichier settings.xml correctement configur.
Crer un plugin
Pas de panique !
Crer de toutes pices un plugin peut faire peur a priori. Nous allons voir, pourtant, que
cela ne nous dpaysera pas beaucoup de notre dveloppement classique avec Maven.
Chapitre 11
175
Nous allons drouler, au cours des paragraphes suivants, la construction pas pas de ce
plugin.
La premire tape ncessite de crer un projet Maven pour notre plugin. Ce projet est
tout ce quil y a de plus classique, la seule exception de son type dassemblage, qui est
maven-plugin.
ASTUCE
Pour crer rapidement un plugin Maven, vous pouvez exploiter un archtype, mais nous en
reparlerons au Chapitre 14, alors ne brlons pas les tapes
1. Plain Old Java Object, soit "bon vieil objet Java". Les outils modernes ne demandent plus notre
code dhriter de telle classe ou dimplmenter telle interface, ce qui lui permet dtre neutre et plus
souple. Cette appellation cherche avant tout se diffrencier des frameworks contraignants qui imposent
la hirarchie des classes, comme Struts par exemple.
176
Partie III
Toutes les caractristiques lies Maven sont dclares dans des balises Javadoc
spciales de notre classe Mojo. Cest ici quHerv va indiquer le nom de la tche et
ventuellement des indications sur les contraintes que le projet doit respecter pour
lutiliser.
Le Listing 11.3 montre le bloc de commentaires Javadoc de notre mojo. Lannotation
@goal indique le nom de la tche. @phase indique la phase dans le cycle de vie pour
laquelle notre mojo a t conu, et laquelle il sera greff par dfaut. Nous associons le
plugin la phase danalyse des sources, qui a lieu avant la compilation.
Nous avons donc un projet Maven capable de produire un plugin qui excutera notre
code Java lors de la phase process-sources. On vous lavait bien dit que ce ntait pas
bien compliqu !
Des paramtres pour le plugin
Le plugin dHerv est un peu tout seul dans son coin. On doit encore lui associer des
paramtres qui permettront dajuster son fonctionnement aux besoins de nos projets.
Loutil danalyse que nous cherchons intgrer produit un fichier de compte-rendu.
Herv va dans un premier temps permettre lutilisateur de dfinir le nom et lemplacement de ce fichier, tout en proposant une valeur par dfaut qui devrait convenir la
majorit des cas.
/**
* Emplacement du fichier de compte-rendu
* @parameter default-value="${project.build.directory}/check.html"
*/
private File output;
Chapitre 11
177
Comme la configuration gnrale du Mojo, les paramtres sont dclars via des annotations " lancienne" dans le Javadoc (aussi connu sous le nom de doclets). Chaque paramtre peut dfinir une valeur par dfaut, qui servira donc de convention pour
lutilisation du plugin. Cette valeur par dfaut peut tre une expression faisant rfrence
un lment du fichier POM. Dans lexemple prcdent, nous identifions par exemple
le paramtre output o loutil danalyse va crire son rapport. Les utilisateurs de notre
plugin pourront modifier ce paramtre dans leur fichier POM en ajoutant dans la configuration un lment <output> avec le chemin de leur choix.
Lexpression dlimite par "${" et "}" permet didentifier des nuds du modle objet
du projet ; rappelez-vous que Maven charge les donnes XML de notre POM en
mmoire sous forme dun arbre dobjets, aprs fusion avec les parents dont il peut
hriter et activation des profils. project.build.directory quivaut ainsi llment
<project><build><directory> du fichier POM.xml du projet, de son parent ou de
la valeur par dfaut de cette proprit. Dans la trs grande majorit des cas, il sagira
du rpertoire target, mais ne prsumons pas de la faon dont notre plugin sera
utilis et des contraintes que vont rencontrer nos projets. Conventions ne signifie pas
obligations !
INFO
Le plus souvent, les plugins Maven utilisent ces expressions pour ne pas coder en dur les
chemins qui correspondent aux conventions. Ce nest cependant pas garanti et cela dpend
du degr de connaissance des dveloppeurs de plugins, et cest lune des raisons pour
lesquelles nous vous encourageons utiliser ces conventions mme si elles ne vous plaisent
pas compltement.
Un modle dynamique
Dans sa premire version, le plugin dHerv, pour analyser notre code
source, utilisait un paramtre bas sur lexpression project.build.sourceDirectory, qui renvoit pour un projet standard le chemin src/main/java.
Herv lance donc son plugin sur le projet devant nos yeux pleins dimpatience et il est
fier de nous prsenter le rapport gnr quelques secondes plus tard dans le rpertoire
target. Applaudissements, puis dsillusion : le code analys est bien celui de notre
projet, mais il en manque toute une partie !
Notre projet utilise un plugin gnrateur de code, transformant un modle UML en
code source Java. Ce code est cr sous target/generated-sources/plugin et na pas
t exploit par loutil danalyse. Oups, boulette. Herv retourne rapidement son
code, quelque peu gn par ce petit contretemps.
178
Partie III
Nous dcouvrons en passant deux autres annotations qui peuvent sappliquer aux
paramtres. @required permet de stopper le build avec un message derreur
adquat si la configuration est incomplte, et @readonly signale que le paramtre
est extrait des structures internes de Maven et non spcifi par lutilisateur dans son
POM.
Nous pouvons ainsi mettre un pied dans les API de Maven et sa modlisation objet dun
projet. Selon la tche raliser, cela pourra tre ncessaire. Linvocation de la mthode
project.getCompileSourceRoots() donnera la liste courante de tous les rpertoires de
fichiers sources.
List<String> sources = project.getCompileSourceRoots();
for ( String root: sources )
{
/// TODO analyser chaque fichier source de ce rpertoire
}
Plexus
Pour toffer son plugin, Herv veut dans notre cas proposer une archive ZIP
du rapport (trs verbeux) gnr par loutil danalyse Geegol, pour que
lutilisateur puisse plus facilement le tlcharger et en conserver lhistorique. Cest ici quintervient la notion de composant, une brique logicielle rutilisable. Les briques en question dpendent de la technologie sur laquelle tourne une
application.
Chapitre 11
179
Maven utilise le conteneur Plexus2 pour lexcution de ses composants. Vous tes
probablement familiaris avec lun de ses concurrents qui remporte un grand succs en
entreprise : SpringFramework. Le fonctionnement de Plexus est relativement comparable, en dehors du mcanisme dannotations qui jusqu peu de temps ne sappuyait que
sur des balises Javadoc la place des annotations de Java 5.
Plexus et Maven mettent disposition un large choix de composants utilitaires que vous
pouvez rfrencer dans des plugins. Herv a besoin dexploiter les capacits dun outil
darchivage, il ajoute en dpendance son projet Maven la bibliothque plexus-archiver.
Il lui reste prsent y accder depuis le plugin.
Comme Spring, Plexus met en uvre le patron dinjection de dpendances 3 (eh oui,
bien que mconnu, Plexus tait trs novateur en son temps !). Ce nest donc pas le
plugin qui va aller chercher un composant mais le conteneur qui va initialiser le
plugin avec les composants dclars comme indispensables. Un composant est rfrenc via lannotation @component et sera inject lors de lexcution de Maven directement au niveau de lattribut. Le composant est identifi par une chane de caractres
qui est, par convention, le nom complet de linterface quil ralise. Lorsque plusieurs
variantes sont disponibles, Plexus propose soit de complter lidentificateur par un
qualificateur complmentaire identifi par le caractre "#", soit de prciser plus explicitement un attribut hint (voir lexemple suivant). Pour faire appel un composant de dcompression darchive ZIP par exemple, on ajoutera lattribut suivant dans
notre plugin :
/**
* Permet de manipuler des archives ZIP
* @component role="org.codehaus.plexus.archiver.Archiver" hint="zip"
*/
private Archiver zipArchiver;
2. http://plexus.codehaus.org/.
3. Aussi connu sous le nom
Inversion_de_contrle).
dInversion
de
Contrle
(http://fr.wikipedia.org/wiki/
180
Partie III
Plexus-utils
En plus des composants Plexus, Herv a besoin de faire de nombreuses manipulations
de fichiers, entre autres pour slectionner la liste des fichiers .java dans nos rpertoires
de code source.
Une bibliothque un peu part dans lcosystme Plexus est plexus-utils. Elle ne
propose pas de composants au sens o nous lavons vu prcdemment, mais un
ensemble de classes utilitaires. En particulier, on y trouve une srie de mthodes de
manipulation de fichiers FileUtils ainsi quun DirectoryScanner, qui permet de
slectionner des fichiers partir dun rpertoire en fonction de patrons Ant dinclusion
et dexclusion.
private List<File> getJavaSources( File root )
{
List<File> files = new ArrayList<File>();
DirectoryScanner scanner = new DirectoryScanner();
scanner.setBasedir( root );
scanner.setIncludes( new String[] { "**/*.java" } );
scanner.scan();
for ( String relativeFilePath : scanner.getIncludedFiles() )
{
files.add( new File( root, relativeFilePath ) );
}
return files;
}
Nous avons donc une mthode qui retourne la liste complte des fichiers sources
Java de notre projet, code gnr inclus ! Reste passer loutil de contrle Geegol
dessus.
Des classes et des royaumes
Une difficult traiter est que le classpath de notre plugin sera constitu en fonction des
dpendances quil dclare, et non en fonction du projet sur lequel nous allons lutiliser.
Nous devrons donc construire un ClassPath combinant le projet avec la dpendance
gea-check de notre plugin pour excuter notre outil dans les conditions ncessaires
son bon fonctionnement.
Pour grer la sparation de ses classes internes et de celles de ses plugins, Maven repose
sur la bibliothque ClassWorlds4. Celle-ci dfinit la notion de royaumes (realm) dans
lesquels on vient ajouter des lments de classpath et, ventuellement, exporter des
packages. Maven met ainsi ses API disposition des plugins sans exposer pour autant
ses classes internes. Il est intressant de voir que cette mme problmatique est releve
4. http://classworlds.codehaus.org/ (voir, en particulier, http://maven.apache.org/guides/mini/
guide-maven-classloading.html).
Chapitre 11
181
de manire indpendante par OSGi, sur lequel on aurait sans doute bti Maven sil avait
t cr en 2009 !
INFO
Si vous ntes pas du tout habitu la notion de ClassLoader, vous pouvez considrer que ce
sont des botes tanches qui disposent chacune dune liste de chemins et de bibliothques
de classes. Plusieurs ClassLoaders cohabitent dans la JVM et partagent un parent commun
correspondant au runtime Java standard. Il est possible pour des classes issues de deux
classloaders de collaborer si elles changent des classes issues dun mme parent.
Vous avez sans doute dj rencontr des problmes de ClassLoaders, de sombres histoires de
classes qui ne sont pas ce quelles disent tre, ou encore des problmes pour la configuration
de la bibliothque commons-logging. Cest un sujet complexe, aussi nous ne nous attarderons pas ;).
Pour notre plugin, nous allons construire un realm ddi lexcution de GEACheck,
incluant ce dernier et ses dpendances ainsi que les chemins daccs au code source. La
Figure 11.1 montre la structure que nous devons mettre en place.
Royaume Maven core
Expose
les API Maven
Royaume du Plugin
Royaume gea-check
Construit
par le plugin
gpp.jar
plexus-utils
GEACheck.jar
plexus-archiver
target/classes
maven-plugin-api
MavenProject
Figure 11.1
Arbre des royaumes ClassWorlds.
182
Partie III
Par souci de clart, nous navons pas indiqu dans ce listing les diverses gestions
dexception qui sont rendues ncessaires par la manipulation dURL. Cette gymnastique est la plus grande difficult rencontre lors du dveloppement dun plugin Maven,
dune part parce que le commun des dveloppeurs nest pas suffisamment laise avec
le concept de ClassLoader, dautre part parce que lAPI Maven-project manque de
documentation.
Listing 11.4 : Construction dun royaume ClassWorlds ddi lexcution de GEACheck
/**
* Dpendances du projet Maven qui utilise le plugin
* @parameter expression=${project.compileArtifacts}
*/
private List<Artifact> projectArtifacts;
/**
* Dpendances du plugin lui-mme
* @parameter expression=${pluginArtifacts}
*/
private List<Artifact> pluginArtifacts;
public ClassLoader createClassLoader()
throws MalformedURLException, DuplicateRealmException
{
ClassWorld world = new ClassWorld();
ClassRealm realm = world.newRealm( "gea-check" );
// Ajout de tous les lments du classpath "compile" du projet
for ( Artifact artifact : projectArtifacts )
{
realm.addConstituent( artifact.getFile().toURL() );
}
// Ajout des dpendances du plugin, comprenant loutil GEACheck
for ( Artifact artifact : pluginArtifacts )
{
realm.addConstituent( artifact.getFile().toURL() );
}
return realm.getClassLoader();
}
ASTUCE
En tant puristes, nous aurions d construire notre royaume en ny incluant que gea-check
et ses dpendances, alors que nous y plaons toutes les dpendances du plugin. Techniquement parlant, les API de manipulation dartefacts et de gestion des dpendances le
permettent mais cest inutilement compliqu. Dans notre cas, le plugin est totalement fonctionnel et quelques classes en trop ne perturbent pas GEACheck.
Chapitre 11
183
Il ne reste plus Herv qu utiliser le ClassLoader que nous venons de construire pour
charger loutil GEACheck et linvoquer avec la liste de fichiers sources java que nous
avons construite prcdemment. Linvocation dune classe depuis un classloader diffrent
du ntre nous oblige passer par la rflexion Java (voir Listing 11.5).
Listing 11.5 : Invocation par rflexion de loutil GEACheck
public void execute()
throws MojoFailureException
{
try
{
ClassLoader cl = createClassLoader();
Class checker = Class.forName( "com.geegol.projectplatform.Checker",
true, cl );
Method main = checker.getMethod( "main", new Class[] { String.class } );
List<String> sources = (List<String>) project.getCompileSourceRoots();
for ( String root : sources )
{
List<File> files = getJavaSources( new File( root ) );
Object[] args = new Object[files.size()];
int i = 0;
for ( File f : files )
{
args[i++] = f.getAbsolutePath();
}
main.invoke( checker, args );
}
}
catch ( Exception e )
{
throw new MojoFailureException( "Erreur lors de la gnration du rapport", e );
}
}
Au-del de Java
Lcriture dun plugin Maven ne se limite pas au langage Java. La JVM peut excuter
de nombreux autres langages, en commenant par Groovy, mais aussi BeanShell,
Ruby, Python ou JavaScript. crire un plugin dans lun de ces langages ne ncessite
que la disponibilit de loutillage de dveloppement de plugin de Maven sur ces environnements.
Groovy est particulirement apprciable pour le dveloppement de plugins
en raison de la facilit avec laquelle il permet les manipulations de fichiers.
Notre ami Guillaume, grand fan de Groovy, relve le dfi et nous propose
une version "groovyfie" de notre plugin (voir Listing 11.6).
184
Partie III
Chapitre 11
185
DuplicateRealmException {
def world = new ClassWorld()
def realm = world.newRealm( "gea-check" )
// Ajout de tous les lments du classpath "compile" du projet
// et des dpendances du plugin, comprenant loutil GEACheck
for (artifact in [*projectArtifacts, *pluginArtifacts] ) {
realm.addConstituent( artifact.file.toURL() )
}
return realm.classLoader
}
public void execute() throws MojoFailureException {
try {
def cl = createClassLoader()
Class checker = Class.forName( "com.geegol.projectplatform.Checker",
true, cl )
def sources = project.compileSourceRoots
for ( root in sources ) {
def files = getJavaSources( new File( root ) )
def args = files.collect { f -> f.absolutePath } as Object[]
checker.main( args )
}
} catch ( e ) {
throw new MojoFailureException( "Erreur lors de la gnration du rapport", e );
}
}
}
186
Partie III
Il faut avouer que les plugins Maven officiels ne sont pas forcment les meilleurs
exemples pour aller piocher de bonnes pratiques, prfrant de lourds tests dintgration un outillage de tests propre chaque plugin ils ont au moins lintrt
dtre outills de tests, ce qui nest pas le cas de nombreux autres plugins indpendants.
La plus grande difficult pour tester un plugin Maven rside dans lidentification
correcte de ce quon dsire valider, en particulier lorsque le plugin sert intgrer un
autre outil : nous devons tre en mesure de valider le fait que loutil a bien t
excut avec le bon paramtrage et non pas que loutil lui-mme est exempt de
bogues.
Plugin testing harness
Maven propose une suite de tests sous forme dobjets simulacres ("mock") pour ses API
et un mcanisme simple pour configurer une instance du plugin tester. Un extrait de
fichier POM est utilis pour dfinir la configuration de test du plugin, et lenvironnement
de test se charge dexcuter le plugin.
La mise en uvre est simple, puisquil sagit dcrire une classe de test jUnit trs classique et de faire appel au plugin-testing-harness pour configurer le plugin que nous
dsirons tester partir dun pseudo-POM, limit sa seule section <plugin>. Le
Listing 11.7 montre le code de ce test, qui va excuter le plugin et vrifier son fonctionnement. Le Listing 11.8 montre le pseudo-fichier POM qui lui sert de base pour
construire et configurer le plugin test.
Listing 11.7 : Test unitaire pour un plugin, bas sur le plugin-testing-harness
public class GEACheckMojoTestCase
extends AbstractMojoTestCase
{
public void testCheck()
throws Exception
{
File testPom = new File( getBasedir(),
"src/test/resources/testCheck.pom" );
Mojo mojo = (Mojo) lookupMojo( "check", testPom );
MavenProject project = new MavenProjectStub();
setVariableValueToObject( project, "compileSourceRoots", new ArrayList() );
project.addCompileSourceRoot( new File( testRoot, "src/main/java"
).getAbsolutePath() );
setVariableValueToObject(mojo, "project", project );
assertNotNull( "Failed to configure the plugin", mojo );
Chapitre 11
187
mojo.execute();
File expected = new File(getBasedir(),
"target/test-target/check/repport.html" );
assertTrue( "expected file not found", expected.exists() );
}
}
ASTUCE
Dans le Listing 11.7, nous utilisons un bouchon de la classe MavenProject. Le plugin plugintesting-harness propose galement des objets bouchons pour de nombreuses autres classes
de lAPI Maven, ce qui permet de construire des tests unitaires qui ncessitent (par exemple)
des manipulations dartefacts.
Plugin invoker
Une seconde option consiste excuter la construction dun projet Maven de test,
mais dans un mode automatis. Cest loption retenue par le plugin invoker, qui va
enchaner un build Maven parallle lors de la phase de test dintgration de notre
projet de plugin. Contrairement au plugin plugin-testing-harness, il ne sagit pas
dexcuter le plugin dans un environnement de test "unitaire", mais de lancer une
construction Maven complte, indpendante et den valider a posteriori la bonne
excution.
Recherchant les fichiers POM placs dans le rpertoire de tests src/it, invoker va utiliser un script Groovy ou BeanShell pour vrifier le rsultat de lexcution. Ce script va
typiquement sassurer que des fichiers attendus en rsultat de lexcution sont prsents
et/ou correctement renseigns.
188
Partie III
Chapitre 11
189
Conclusion
Ce chapitre a dmontr que lcriture dun plugin Maven nest pas une tche fondamentalement dlicate, mme si elle prsente quelques subtilits (voir dailleurs, ce sujet,
http://maven.apache.org/plugin-developers/common-bugs.html). Dans de nombreux
cas, le dveloppement dun plugin ne ncessite pas de soulever le capot de Maven audel de la classe AbstractMojo. Cependant, lutilisation des annotations Plexus et de lAPI
Maven peut rebuter de nombreux dveloppeurs, et il faut bien reconnatre que la documentation sur le sujet nest pas irrprochable. Les bons exemples ne manquent cependant pas et la communaut des dveloppeurs Maven est prte apporter tout le support
ncessaire.
12
Lassurance qualit
Une application qui fonctionne, cest bien. Mais du code qui est correctement construit,
volutif, lisible, maintenable, cest mieux. Lassurance qualit est un exercice dlicat
qui tente de canaliser la crativit dbordante des dveloppeurs pour viter lanarchie
sans pour autant restreindre leur productivit ou leur capacit dinnovation. Matriser
un projet, cest aussi savoir en extraire les indicateurs de qualit adquats et se donner
les moyens den suivre lvolution.
Audit de code
Lors de notre intgration au sein de Geegol, notre projet a subi les regards inquisiteurs
de ceux qui allaient devenir nos collgues. Habitudes diffrentes obligent, certaines
tournures de notre code ne collaient pas avec la culture locale. Si la qualit dun projet
tait value sur des critres purement subjectifs de ce niveau, nous serions bons pour
une rcriture complte, coteuse et probablement inutile. Par contre, certains aspects
de notre projet mriteraient peut-tre une analyse plus minutieuse nous ne pouvons
pas tre experts en tout !
Les outils daudit de code ont lintrt dtre objectifs. Bien sr, les rgles quon leur
demande de vrifier ont t choisies et pondres selon des critres propres lentreprise, mais au moins elles sont clairement identifies et justifies. Si le groupe a fait le
choix de mettre laccent sur la qualit de documentation, il poussera au maximum les
mtriques concernant la Javadoc et le nombre de lignes de code sans commentaire. Cela
ne garantit en rien un code bien document, mais cela donne tout de mme une indication
partir de laquelle on peut travailler.
Les outils daudit sont lgion, et ils produisent des rapports plus ou moins complexes
analyser (du moins pour un dveloppeur lambda). Le monde open-source en fournit
192
Partie III
une jolie panoplie, dont le seul dfaut est de ne pas tre intgre. Chaque outil va
produire un rapport, dans un format propre, quil nous faudra plucher.
Par ailleurs, lintrt de ces outils nest pas de faire des audits ponctuels pour donner
une note une quipe de dveloppement. Si on en arrive l, cest quils sont utiliss
bien trop tard. Leur plus-value apparat dans les indicateurs synthtiques quils fournissent et quon peut suivre au cours de la vie du projet ds que du code est crit, signalant
ainsi toute drive malheureuse dans les bonnes pratiques de dveloppement.
Vincent sattaque outiller notre projet pour rpondre au mieux aux attentes
du groupe. Il pluche la longue liste des outils disponibles pour en tirer le
meilleur et proposer une bote outils conviviale et pertinente. Son objectif
est de dmontrer notre capacit de raction, avant que la cellule qualit ne rende son
verdict aprs dix jours daudit de notre code. Pour chaque problme identifi, il veut
tre capable de rpondre :
m
que nous disposons de loutillage ncessaire pour nous assurer quil ne se reproduise plus ;
Avec un dossier de dfense aussi bien ficel, nous devrions en principe viter de voir
trop de monde fourrer son nez dans notre code et nous prendre de haut pour nous expliquer comment bien travailler. Nous avons tout de mme notre fiert, et noubliepaslalistedescourses reste notre bb !
Analyse statique
Une premire catgorie doutillage concerne lanalyse statique du code. Il sagit dune
relecture du code par un outil qui va rechercher des patrons particuliers et calculer des
mtriques. En Java, il existe plusieurs outils de cette catgorie, lesquels peuvent
extraire :
m
Chapitre 12
Lassurance qualit
193
Le premier type dindication est videmment celui qui attire tout de suite nos dcideurs : comment rsister un outil qui, en quelques clics, va identifier tous les bogues
si coteux que nous avons ngligemment laisss traner ?
Checkstyle
return courses;
}
La diffrence entre ces deux fichiers sources est minime, cependant les outils de fusion
automatique ne savent pas la grer et obligent Vincent vrifier ligne par ligne la
concordance des deux versions concurrentes.
194
Partie III
Lhomognisation, surtout si elle est pousse outrance, peut tre ressentie parfois
comme une faon de brider lappropriation du code par les dveloppeurs. Vouloir que
tout le monde travaille strictement de la mme faon cest, en effet, faire de nous de
simples machines coder sans libert individuelle. Par contre, laisser chacun faire ce
quil veut sa sauce nest pertinent que si cela ne vient pas perturber les autres. Pour
faire intellectuel, disons que "la libert des uns sarrte l o commence celle des
autres".
Mme si cela va ncessiter de se poser pendant une heure et obliger certains dentre
nous accepter un formalisme quils napprcient pas forcment, se mettre daccord
sur des rgles de ce type conomisera chacun de longues heures dun travail inutile,
rbarbatif et source derreurs. Sans compter que notre IDE prfr sait nous aider
formater le code la vole !
Les rgles, mme les plus superficielles, de Checkstyle ont donc leur rle. Lanalyse du
code signalera directement que le petit dernier arriv dans lquipe ne respecte pas nos
rgles communes et va un moment ou un autre provoquer le problme rencontr par
Vincent et Herv.
Checkstyle compte galement de nombreuses rgles qui valident le niveau de documentation technique du code. Ici aussi, pas de rgle gnrale : du code peut tre lourdement
comment et totalement incomprhensible, le commentaire peut dailleurs tre totalement obsolte, et du code sans commentaires est parfois extrmement limpide et ne
ncessite aucune explication complmentaire. Cependant, si nous dfinissons un niveau
de documentation que nous considrons souhaitable pour notre projet, Checkstyle saura
indiquer nos points faibles ou notre relchement.
Enfin, Checkstyle propose quelques rgles plus techniques sur lutilisation des mots
cls et des structures de code. Une fois encore, la slection de ces rgles et leur pondration sont un travail que nous devrons affiner au fur et mesure de notre utilisation de
loutil. Activer toutes les rgles napporte rien, linformation tant noye dans la masse.
Cest mme contre-productif, puisque a amne penser que loutillage est inutilisable
car trop tatillon.
FindBugs
Chapitre 12
Lassurance qualit
195
Plutt que de le considrer comme un juge intransigeant, il faut voir FindBugs comme
un conseiller qui cumule la connaissance des erreurs ralises par des centaines de
dveloppeurs et est capable de les identifier. Sa base de donnes de choses ne pas faire
se distribue entre mauvaises pratiques, dfauts de performances, dysfonctionnements,
incompatibilit avec un mode multithread et problmes de scurit.
Une fois de plus, activer toutes ses rgles sans se soucier du contexte risque surtout de
produire un rapport de milliers de lignes peine exploitable. Cest nous de comprendre chacune de ses rgles, de voir si elle sapplique notre projet et limportance que
nous lui donnons. La simple lecture de ces rgles est dailleurs trs formatrice !
Nous pouvons galement assister FindBugs dans son travail danalyse pour le rendre
plus pertinent. Des annotations comme @NonNull peuvent tre ajoutes dans le code
pour prciser, par exemple, quune mthode naccepte pas un appel sans un paramtre
correctement renseign (fonctionnalit qui est dailleurs propose pour Java 7). La
prsence de cette annotation permet loutil de contrler tous les endroits o elle est
invoque et, en mme temps, complte la documentation de notre code en prcisant nos
intentions.
De la mme faon, FindBugs peut exploiter les annotations dfinies en marge du livre
Programmation concurrente en Java, de Brian Goetz chez le mme diteur, excellent
ouvrage que je vous recommande ;) pour identifier les problmes de gestion concurrente en environnement multithread.
PMD
196
Partie III
Le second, beans, correspond des classes de donnes sans valeur ajoute : juste
des beans ayant des accesseurs get/set, mais cela fait dj pas mal de lignes de code,
do le mauvais rsultat de la mesure.
Chapitre 12
Lassurance qualit
197
Un taux de couverture infrieur la moyenne doit tre justifi. Pas de taux absolu et inexplicable
atteindre mais, par contre, interdiction de dlaisser une partie de lapplication sans bonne
raison.
198
Partie III
Chapitre 12
Lassurance qualit
199
gement>.
Le plugin site se base sur un fichier ddi, src/site/site.xml, dans lequel est dcrite
la structure gnrale de notre site web. Ce fichier nous permet dorganiser le menu
gnral du site et de pointer vers nos principales pages documentaires. Le Listing 12.1
montre celui mis en place par Lukas pour notre projet.
Listing 12.1 : Le descripteur de notre site
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/DECORATION/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/DECORATION/1.0.0
http://maven.apache.org/xsd/decoration-1.0.0.xsd"
name="N'oublie pas la liste des courses">
<bannerLeft>
<name>N'oublie pas la liste des courses</name>
<src>http://www.noubliepaslalistedescourses.fr/images/logo.png</src>
<href>http://www.noubliepaslalistedescourses.fr</href>
</bannerLeft>
<body>
<links>
200
Partie III
Selon un format APT (Almost Plain Text), proche dune syntaxe wiki et rapidement
assimil.
Chapitre 12
Lassurance qualit
201
Comme le plugin site et son fichier site.xml, le plugin pdf sappuie sur un descripteur pdf.xml qui lui indique comment assembler les lments documentaires pour
produire le rsultat. De la mme faon, et avec les moteurs de rendu adquats, Doxia
pourrait produire notre documentation dans tout un ensemble de formats quil reste
imaginer (voir Figure 12.1).
Document
pdf
Maven-Pdf-Plugin
Pdf.Xml
Wiki
Confluence
Fichiers
APT, xdoc,
fml, ...
Doxia
Maven-Site-Plugin
PMD
Site.Xml
Checkstyle
Projet
Maven
Site web
FindBugs
Rapport
Cobertura
JavaDoc
...
Figure 12.1
Gnration de la documentation en diffrents formats grce Doxia.
202
Partie III
Nous sommes tous attentifs ces rapports danalyse de code que nous pouvons dsormais construire sur notre poste de dveloppement, moins de consulter le site gnr
toutes les nuits sur notre serveur dintgration continue il serait dommage quil reste
inutilis pendant cette priode o nous, pauvres humains, devons nous reposer. Nous
pouvons identifier les lments de code qui violent des rgles et corriger consciencieusement ces dfauts, esprant ainsi que les chiffres du lendemain seront meilleurs.
68 %, qui dit mieux ?
Rapidement, un besoin nouveau sexprime : lorsque nous constatons quun lment du
projet est sous-document, nous ajoutons quelques fichiers APT pour combler le
manque. La perception de ce dfaut de documentation est totalement subjective mais
nous arrivons rapidement un consensus sur le niveau obtenu. Par contre, le rapport
indiquant le taux de couverture de nos tests est plus dlicat interprter. 68 %, est-ce
bien ? Est-il utile de vouloir pousser ce taux au-del, ce qui pourrait rapidement nous
amener crire des tests sans intrt juste pour approcher des 100 %. Pire, nous pourrions tre tents dcrire de nombreux tests faciles pour obtenir un bon chiffre en dlaissant
des parties de code moins videntes tester.
68 %, a ne veut rien dire. Ce qui est intressant, cest de voir que le mois dernier, nous
tions pour le mme package 82 % ! Il semble que nous avons laiss cette partie du
projet se dgrader ! moins que nous nayons une bonne explication pour cette baisse,
une action doit tre entreprise pour corriger le tir.
Les indicateurs qualit sont rarement trs pertinents tels quels, et, en tout cas, la valeur
cible respecter dpend du contexte du projet, de ses objectifs et souvent de llment
technique considr. Notre code daccs la base devrait tre proche de 100 % de
couverture de test, sinon cela voudrait dire que certaines requtes ne font pas lobjet
de tests et quune modification dans notre modle ne serait pas dtecte. De mme, tous
les aspects fonctionnels (le code mtier utile) doivent tre largement couverts. En
revanche, dautres parties de notre code, prsentant de nombreux cas derreurs qui ne
donnent pas lieu un traitement prcis autre que "erreur interne, merci de ressayer
plus tard", peuvent lgitimement obtenir une couverture moindre.
Lentropie augmente
Il nexiste pas de juste milieu absolu. Nanmoins, on constate lapplication universelle
du second principe de la thermodynamique : le code tend toujours se dgrader pour
devenir moins organis et moins bien test. Des tests obsoltes sont supprims, le
nouveau code crit dans la chaleur dun coup de bourre est peu ou pas instrument
Juste maintenir le code au mme niveau demande une dbauche dnergie, de temps et
donc de budget !
Chapitre 12
Lassurance qualit
203
Pour dtecter rapidement une telle drive, rien ne vaut un bon graphe synthtique historisant lvolution du projet. De manire assez amusante, on peut souvent deviner les
dates de livraison sur de telles courbes : on constate un inflchissement de la courbe
dans la semaine qui prcde la livraison et (dans le meilleur des cas) une reprise lente
dans les semaines qui suivent.
Matrise de S2
Le spcialiste en thermodynamique de lquipe cest Vincent, et cest donc
lui qui nous propose spontanment un outil pour tre en mesure de mesurer lentropie de notre projet. Il a dj pass de longues heures analyser
les nombreux rapports produits par Maven dans notre site et a rapidement compris
que ce ne sont que des donnes brutes. Il faut tre capable de les lire des altitudes
diffrentes :
m
30 000 pieds, on doit avoir en un coup dil une vision globale du projet, trs
imparfaite mais parlante. Le projet est-il dans le rouge ou non ? Quel est le type de
violation le plus couramment constat et sur lequel il faudra faire un effort de
communication et de formation ?
3 000 pieds, on doit tre en mesure didentifier les modules et de distinguer celui
qui joue le mouton noir (esprons quil ny en ait quun seul), la rgle de codage la
moins bien respecte.
300 pieds, on peut pointer du doigt les packages dans lesquels il serait bon de
passer un peu plus de temps, ou la rgle de codage dont les dveloppeurs ont sans
doute mal compris la porte.
1 mtre, on droule le code source ligne par ligne et on y identifie chaque violation. En binme avec le dveloppeur qui a eu la maladresse dcrire ce code, on peut
discuter du bien-fond de la rgle et des faons dcrire un code plus propre et plus
conforme nos exigences.
2. Petit rappel de vos lointains cours de physique : S est le symbole utilis en physique pour
lentropie :).
204
Partie III
Sonar
Sonar3 est une application web qui va stocker dans une base de donnes tous les indicateurs et statistiques extraits par nos rapports danalyse de code. En outil convivial et
soucieux de sa simplicit dutilisation, il est propos avec un serveur dapplication et
une base de donnes embarqus, ce qui limite la procdure dinstallation au strict minimum. Pour une utilisation en entreprise de manire plus stratgique, on pourra cependant le dployer sur un serveur et le configurer pour utiliser une base de donnes ddie.
Les donnes de Sonar sont accessibles via un frontal web synthtique, qui donne les
grandes tendances du projet. Cest notre vue 30 000 pieds du projet (voir
Figure 12.2).
Figure 12.2
Synthse de nos indicateurs qualit dans Sonar.
La reprsentation du projet en blocs colors est particulirement compacte et pertinente. Pour un critre donn ici, le respect des rgles de codage , un bloc de grande
3. http://sonar.codehaus.org/.
Chapitre 12
Lassurance qualit
205
Figure 12.3
Dtail des violations constates par Sonar dans notre code source.
Sonar va extraire de notre projet Maven lensemble des indicateurs quil prend en
charge via un plugin ddi. Celui-ci va directement enrichir la base de donnes du
serveur Sonar pour la construction en cours. Le serveur exploitera ensuite les donnes
pour fournir une synthse ainsi quun historique. Le Listing 12.2 montre la configuration de ce plugin dans notre POM. Le plugin sonar utilisant de nombreuses proprits,
il est plus simple de les configurer comme telles et dinvoquer la tche mvn
sonar:sonar.
Listing 12.2 : Configuration du plugin Sonar
<profile>
<id>sonar</id>
<properties>
<sonar.host.url>http://sonar.geegol.com</sonar.host.url>
206
Partie III
<sonar.jdbc.url>jdbc:mysql://mysql.geegol.com:3306/SONAR?autoReconnect
=true</sonar.jdbc.url>
<sonar.jdbc.driver>com.mysql.jdbc.Driver</sonar.jdbc.driver>
<sonar.jdbc.username>sonar</sonar.jdbc.username>
<sonar.jdbc.password>sonar</sonar.jdbc.password>
</properties>
</profile>
Pour produire ces mtriques de notre projet intervalles rguliers, nous dcidons de
laisser notre serveur dintgration continue effectuer une construction ddie toutes les
nuits il faut bien rentabiliser la machine. Sur notre serveur Hudson, nous avons la
bonne surprise de dcouvrir un plugin ddi Sonar, qui nous conomise la configuration de cet outil dans notre POM. Il suffit de fournir quelques paramtres dans la
console dadministration de Hudson et de configurer une construction du projet heure
fixe.
Nous constatons que la complexit mesure de notre code grimpe rgulirement
(voir Figure 12.4). Cest une drive typique qui prend pied de manire maligne,
rpartie un peu partout dans le code et sans que personne sen sente responsable. Il
est temps de sensibiliser lquipe, par exemple en lui montrant cette simple courbe,
sur linfluence que peut avoir un petit effort quotidien de clarification et de simplification du code.
Figure 12.4
volution de nos indicateurs qualit.
Chapitre 12
Lassurance qualit
207
La Figure 12.5 indique galement le Top 10 des violations constates, ce qui nous dira
immdiatement sur quoi nous devons mettre laccent. Notre session mensuelle de
dbriefing est dj toute trace !
Sonar nest dfinitivement pas un outil de flicage, cest un assistant extrmement puissant pour accompagner le travail dune quipe et pointer du doigt ses drives. Le dveloppeur parfait nexiste pas, mais le dveloppeur bien outill peut tenter de samliorer.
Figure 12.5
Classement des violations les plus souvent identifies.
Conclusion
Accompagner notre projet dun bon support documentaire et dun bon suivi qualit est
une tche ambitieuse, qui peut sappuyer sur de trs nombreux outils. Inutile de vouloir
se surquiper si on nen a pas compris lutilisation. Maven aide mettre en place les
outils progressivement, apprendre les exploiter. Notre ingnieur qualit devrait en
toute logique nous aider accomplir cette initiation et, une fois mrs, nous pourrons en tirer
tout le bnfice.
Maven nest ici que le catalyseur qui nous aide utiliser des outils existants. Cependant, la facilit avec laquelle on introduit un outil danalyse dans un projet Maven
encourage lessayer, en dcouvrir lusage, et progressivement mettre en place une
culture du coder proprement (livre de Robert C. Martin que je vous recommande
chaudement, chez le mme diteur).
13
Respecter un format de distribution
Nous avons produit avec Maven un ensemble de binaires respectant les formats imposs par la plateforme Java et la norme JEE. Il nous reste envoyer le rsultat de notre
dur labeur pour la mise en production. Nous entrons alors dans une longue procdure de
dclaration et de mise en conformit. De toute vidence, lquipe charge dinstaller, de
configurer et de surveiller les serveurs dapplications, a largement de quoi soccuper
avec ses propres problmes pour ne pas vouloir se plier nos caprices. nous de lui
fournir un livrable qui colle ses outils et ses bonnes pratiques pour une mise en
production russie.
Do vient ce JAR ?
Depuis que nous avons mis en place un mcanisme dintgration continue, nous en
avons tir de nombreux avantages, parmi lesquels le fait de disposer en permanence de
la dernire version stable et teste de nos binaires, ce qui nous vite de construire lintgralit du projet sur nos postes de dveloppement. Le projet commenant prendre de
lembonpoint force dexplorer de multiples directions, cest un avantage important en
termes de productivit tel point que nous avons rapidement pris lhabitude dutiliser
ces binaires issus de lintgration continue comme fourniture notre quipe de test
pour valider la bonne communication avec les systmes partenaires et la tenue des
performances.
Le gain de temps et de stabilit est significatif. Plutt que de perdre des heures prparer une version ddie aux tests, nous avons toujours notre disposition un livrable prt
tre test pas forcment complet mais fonctionnel. Par ailleurs, nous sommes srs
que cette fourniture respecte nos critres qualit puisquelle est issue de notre fabrique
logicielle. Nous entrons ainsi dans une phase dindustrialisation durant laquelle un
processus automatis produit notre livrable avec loutillage qualit adquat.
210
Partie III
Notre livrable est ainsi construit sous le nom noubliepaslalistedescourses-1.2.0SNAPSHOT-build-792. La consultation de lhistorique de notre intgration continue
indiquerait immdiatement quel code source correspond ce build 792. Nous pouvons
dailleurs demander au serveur dintgration continue de conserver soigneusement les
traces dune construction dont nous livrons le rsultat lquipe de test et de placer une
marque dans le gestionnaire de code source en consquence.
Chapitre 13
211
Numro de rvision
Une solution alternative, lie lutilisation du gestionnaire de code source Subversion,
est la notion de rvision. Sur Subversion, chaque commit cest tout le rfrentiel qui
voit son numro de rvision incrment, et pas juste le fichier modifi. On arrive ainsi
rapidement des numros de rvision cinq ou six chiffres.
Si cela na aucune influence sur le dveloppeur, cela fournit un moyen de lier un livrable son code source de manire extrmement prcise : si le binaire a t construit
partir de la rvision 4704, il suffit dextraire de SVN ltat du code source associ. Nous
pouvons dailleurs demander a posteriori Subversion de poser une marque pour le
code associ cette rvision particulire.
Avantage par rapport au numro de construction, ce numro de rvision nest pas li au
serveur dintgration continue et peut tre obtenu sur nimporte quel poste de dveloppement. La mme construction donnera donc le mme rsultat, ce qui est la moindre
des choses ! Le Listing 13.2 montre lutilisation du plugin buildnumber pour obtenir ce
numro de rvision et lexploiter sous forme de variable Maven. noter quil est
dclench dans la phase prepare-package disponible dans Maven 2.1 et versions ultrieures.
Listing 13.2 : Obtenir le numro de rvision SVN
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>buildnumber-maven-plugin</artifactId>
<executions>
<execution>
<phase>prepare-package</phase>
<goals>
<goal>create</goal>
</goals>
</execution>
</executions>
<configuration>
<doCheck>false</doCheck>
<doUpdate>false</doUpdate>
</configuration>
</plugin>
</plugins>
<finalName>${project.artifactId}/${project.version}-rev-${svnnumber}</finalName>
</build>
212
Partie III
Utiliser le MANIFEST
Dcid ne pas se faire avoir deux fois, Lukas met en place cette solution et
fait produire par notre serveur dintgration continue des binaires portant
systmatiquement lindication de rvision SVN dans le nom du fichier. Il est
cependant rapidement ramen la dure ralit lorsquil constate que la dernire version
disponible de lEAR dans notre gestionnaire de bibliothque sappelle noubliepaslalistedescourses-1.2.0-SNAPSHOT.ear oups !
Nous avons jusquici cherch modifier le nom du fichier produit par Maven. Cest
oublier que la phase de dploiement dans notre dpt de bibliothques nen tient pas
compte : le binaire qui est dploy respecte scrupuleusement les indications d artifactId et de version ! Malgr nos efforts, et mme si le rpertoire target contient
bien au final un fichier noubliepaslalistedescourses-1.2.0-SNAPSHOT-rev-4704.ear,
le fichier que nous retrouvons dans notre dpt ne possde plus ce complment dinformation.
En fait, nous avons aussi cherch rinventer la poudre. Le format darchive Java ( JAR,
WAR ou EAR) nest pas juste une extension maison pour une compression de type ZIP.
Ce format dfinit aussi un mcanisme de mtadonnes via le rpertoire spcialis
META-INF, et en particulier le descripteur MANIFEST.MF.
Ce fichier nest rien dautre quun fichier texte, dont le formalisme est un peu droutant parfois mais qui ressemble globalement aux fichiers de proprits que vous
manipulez dj certainement. Pour une cl donne, on associera une valeur, par
exemple pour la cl build le numro de construction de notre serveur dintgration
continue.
Comment complter ce fichier MANIFEST ? La construction de nos projets par
Maven en produit naturellement un, avec des informations minimalistes. Il suffit de
demander aux plugins jar, war ou ear dajouter dautres informations. Le
Listing 13.3 montre la configuration mise en place par Lukas pour aboutir une
solution enfin satisfaisante et pleinement reproductible. Notez aussi lutilisation
dun profil ddi lintgration continue qui permet de complter ces mtadonnes,
lorsque des informations complmentaires sont disponibles, et de ne pas perturber le
fonctionnement de Maven sur les postes de dveloppement (le plugin buildnumber1
nest pas trs performant).
1. http://mojo.codehaus.org/buildnumber-maven-plugin/.
Chapitre 13
213
214
Partie III
Avec cette configuration, chacun de nos binaires portera dsormais les informations
compltes de ses origines. En cas de besoin, il nous suffira de les exploiter pour retrouver rapidement le code source associ, et ventuellement les traces de sa construction
dans notre serveur dintgration continue.
La confiance rgne
Stphane revient lair sombre dune longue runion avec les responsables
stratgiques du groupe. Il leur a expos nos pratiques, nos outils et les avantages en termes de productivit et de stabilit que nous tirons du couple intgration continue/gestionnaire de dpt. Il sest alors cass les dents sur un expert en
scurit, certifi CISSP-ISSMP, CISA, etc., un adepte du chiffrage des cls asymtriques et autres mcanismes que nous utilisons tous les jours sans nous en rendre compte
mais que peu de monde est capable dexpliquer.
Notre M. Scurit a juste tiqu lorsque Stphane a expliqu que chaque poste de dveloppement rcupre depuis un serveur les bibliothques dans leur dernire version
stable.
"Qui valide cette stabilit ?
Le serveur dintgration continue, avec son armada de tests, de mtriques et de rgles
qualit.
Est-il le seul pouvoir publier des binaires sur ce serveur ?
En principe, tout dveloppeur peut galement publier les binaires du projet sur lequel
il travaille, a peut parfois tre utile dailleurs pour propager rapidement une correction,
mais en pratique
Mais alors, il nest pas possible de sassurer de qui a produit le binaire ?
Eh bien, nous pourrions lajouter dans le MANIFEST, justement rcemment nous
lavons complt du numro de rvision
Mais comment tre sr que cette information est fiable ?
Euh vous voulez dire que quelquun se ferait passer pour un autre ?
Oui : un employ ayant un compte rgler, ou pire, un pirate informatique !
Eh bien"
Chapitre 13
215
2. http://fr.wikipedia.org/wiki/GPG.
216
Partie III
<id>sign-artifacts</id>
<phase>verify</phase>
<goals>
<goal>sign</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
...
</project>
Chaque dveloppeur qui dsire diffuser un binaire sur le dpt verra ainsi son nom
grav dans le marbre du MANIFEST et le fichier binaire sign numriquement par sa
cl GPG. Voil de quoi donner du rpondant Stphane pour sa prochaine runion !
Nous ne pouvons donc pas nous contenter de produire notre EAR avec Maven, il nous
manque une tape, et vous imaginez que nous nallons pas arrter notre dmarche
dautomatisation complte du processus si prs du but !
Chapitre 13
217
Assemblage du livrable
La production rclame une archive Unix tar.gz rpondant une structure trs prcise :
m
Nous avons dj vu un joli panel de plugins qui nous ont bien aids dans notre travail ;
nous allons faire appel au plugin assembly, lun de leurs petits frres. Ce plugin va
exploiter un fichier XML qui dcrit le livrable assembler. Dans ce fichier, nous indiquerons les constituants de notre archive.
Le fichier assembly comptera trois parties, correspondant aux trois constituants cls de
notre archive cible. Ce fichier est structur par un schma XML qui nous aidera viter
les erreurs de syntaxe. Len-tte du fichier indique le format darchive produire : une
archive TAR compresse GZip. Nous pourrions aussi bien produire une archive ZIP ou
un TAR non compress.
La suite du fichier indique au plugin assembly les lments du projet ajouter dans
larchive. La premire partie va piocher dans notre projet multimodule (voir le Chapitre 7) celui qui produit larchive EAR. Nous pourrions le dsarchiver ou le faire accompagner de ses dpendances. La deuxime va inclure une liste de fichiers identifis dans
un rpertoire prdfini. La dernire va parcourir tous les modules du projet et en
extraire le code source. Le Listing 13.5 montre ce fichier magique qui nous fera franchir la dernire ligne droite avant une production 100 % automatise de notre livrable.
Listing 13.5 : Le fichier assembly
<?xml version="1.0" encoding="UTF-8"?>
<assembly xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/assembly-1.1.1.xsd">
<id>livrable</id>
<formats>
<format>tar.gz</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<moduleSets>
<moduleSet>
<!-- inclusion de l'EAR -->
218
Partie III
<includes>
<include>com.geegol.shoppinglist:shoppinglist-ear</include>
<includes>
<binaries>
<unpack>false</unpack>
<outputFileNameMapping>shoppinglist.ear</outputFileNameMapping>
<outputDirectory>application</outputDirectory>
<includeDependencies>false</includeDependencies>
</binaries>
</moduleSet>
<moduleSet>
<!-- inclusion des fichiers sources de chaque module -->
<sources>
<includeModuleDirectory>false</includeModuleDirectory>
</sources>
</moduleSet>
</modulesSets>
<fileSets>
<!-- inclusion des fichiers de configuration -->
<fileSet>
<directory>src/main/configuration</directory>
<lineEnding>unix</lineEnding>
<outputDirectory>configuration</outputDirectory>
<includes>
<include>**/*.xml</include>
<include>**/*.properties</include>
</includes>
<fileMode>755</fileMode>
</fileSet>
</fileSets>
Le format de ce fichier utilise un schma XML qui nous assistera dans sa saisie et qui
est largement document sur le site web du plugin3.
ASTUCE
Le plugin assembly propose quelques descripteurs types pour des usages courants, comme
produire, en parallle du livrable, un ZIP des sources. Un autre assembly qui pourra tre utile
est le jar-with-dependencies qui construit un gros JAR du projet avec toutes ses dpendances. Cest bien pratique si on doit fournir des outils en ligne de commande (traitements
batch, par exemple), dont le lancement pourra alors se rsumer java -jar monJar.
Pour produire notre livrable tant dsir, il nous suffit de lancer la commande mvn
assembly:assembly. Nous lavons dj vu, cette syntaxe correspond linvocation
dune tche spcifique dun plugin et non dune phase de construction du projet.
3. http://maven.apache.org/plugins/maven-assembly-plugin/.
Chapitre 13
219
Solution miracle ? Eh bien non, chec cuisant. Le plugin assembly plante lamentablement en indiquant quil ne trouve pas notre EAR :(.
220
Partie III
Luf ou la poule ?
Quel est le problme ? Il nous faut comprendre un peu mieux les rouages de Maven
pour expliquer cet chec : nous avons mis en place lhritage naturel sur le projet, cest-dire que le mme fichier POM sert dclarer nos modules et de parent commun pour
mutualiser la configuration et les dpendances. Cette solution, bien pratique, est largement
applique mais pose ici un problme :
m
En tant que support du plugin assembly, notre POM parent doit passer en revue les
modules du projet. Le plugin pourra ainsi en extraire la structure et les binaires
produits.
En tant que parent, notre POM doit tre totalement constitu avant que ses fils puissent tre construits. Cela signifie que Maven doit excuter son cycle de vie avant de
pouvoir sattaquer aux modules.
Ces deux contraintes contradictoires sont une voie sans issue. Pour contourner cette
impasse, nous utilisons une astuce qui ressemble plus un hack qu une vraie solution,
mais qui va bien nous dpanner.
Nous crons ct de notre fichier racine pom.xml un second fichier POM : pom-assembly.xml. Dans ce nouveau descripteur Maven, nous plaons la configuration du plugin
assembly, ainsi que la dclaration dun unique module qui pointe vers le pom initial. Le
Listing 13.7 montre ce nouveau fichier, particulirement simple compar au volume de
XML que Maven peut parfois nous demander de saisir.
Listing 13.7 : Un POM ddi lassembly
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.geegol.shoppinglist</groupId>
<artifactId>shoppinglist-assembly</artifactId>
<version>1.7.1-SNAPSHOT</version>
<packaging>pom</packaging>
<modules>
<module>.</module> <!-- le POM.XML qui est juste ct ! -->
</modules>
<build>
<defaultGoal>install</defaultGoal>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
Chapitre 13
221
... )
</plugin>
</plugins>
</build>
</project>
En lanant Maven avec loption -f, nous pouvons indiquer le fichier POM utiliser
comme base de la construction du projet. mvn assembly:assembly -f pom-assembly.xml va donc provoquer la construction de ce POM minimaliste, lexcution du
plugin assembly, qui va, son tour, provoquer la phase package sur lensemble des
modules du projet.
Nous venons de rsoudre le problme de luf et de la poule !
OSGi ?
Il reste un point que nous navons fait quvoquer, il sagit de la norme
OSGi. Celle-ci vient sur de nombreux points marcher sur les platesbandes de Maven. Elle gre en effet la notion de dpendances, de
versions et de rglement des conflits qui en rsultent, mais via le fichier MANIFEST standard des archives Java. Jason nest pas prs de baisser les bras et sattaque ce
problme.
Il existe dj des plugins Maven visant convertir les mtadonnes du POM dans le
MANIFEST. Ils ont t dvelopps en marge des premiers middlewares OSGi.
Loutillage de rfrence pour les dveloppeurs OSGi reste cependant lIDE Eclipse.
Bas sur limplmentation equinox dOSGi, celui-ci propose un environnement
complet de dveloppement pour cette plateforme, avec assistants graphiques et
autres outils confortables qui nous font oublier les plaisirs de la ligne de
commande.
Jason vise donc une autre approche : partir des outils existants et faire le bout de chemin
qui manque pour les mener jusqu Maven. Pour laider dans ce plerinage, il se base
sur Tycho4, une variante de Maven spcialement repense pour rpondre aux exigences
de la norme OSGi. Tycho propose de lire les mtadonnes OSGi et de les convertir au
format Maven. Il devient donc possible de construire, via Maven, un projet dvelopp
dans le Plugin Development Environment dEclipse, dexploiter le rpertoire plugins
dEclipse comme rfrentiel dartefacts et dexcuter les tches Maven classiques sur
cette base.
4. http://docs.codehaus.org/display/M2ECLIPSE/Tycho+user+docs.
222
Partie III
Ce pont entre deux mondes est encore trs exprimental. Sans doute encore trop fragile
pour des dveloppements professionnels, il apparat pourtant comme les prmices dun
mariage entre un outil reconnu et une norme qui voit de plus en plus dditeurs sy intresser.
Conclusion
Notre software factory (cest un mot la mode, mettez-le sur votre CV) est dsormais
bien rode. Elle construit automatiquement un livrable :
m
Clairement identifi.
Respectant nos critres qualit et rgles de codage, dont les mtriques sont historises.
Mis disposition de tous les dveloppeurs qui veulent le tester ou bnficier des
dernires corrections.
Le chemin a t long depuis notre petit projet rigolo chang par e-mail, et loutillage a
largement progress. Si la taille de nos fichiers pom.xml peut faire peur certains, il ne
faut pas perdre de vue le nombre de services que Maven propose via une commande
unique.
Nous pourrions encore dployer lapplication de manire automatise sur un serveur
JEE, sous rserve quil existe un plugin Maven adapt (ce qui couvre quasiment tous les
cas lexception notable dIBM Websphere). Lquipe de production prfre souvent
conserver la main en choisissant elle-mme quand et par qui une mise jour est ralise. Cette retenue est comprhensible de la part de ceux qui sont en premire ligne en
cas de dysfonctionnement, et qui nont pas encore mesur le gain de fiabilit que lintgration continue, bien instrumente, peut nous apporter. Sans ce dernier rempart, nous
passerions de lintgration continue la production continue, volution de lindustrie
logicielle qui nest pas encore dans les murs, mais que Maven peut dj supporter !
14
Un nouveau projet dmarre
Avec tous nos efforts sur notre projet noubliepaslalistedescourses pour mettre en uvre
les meilleures pratiques et les outils les plus aboutis, dans un souci constant dintgration et dautomatisation, nous commenons faire parler de nous. tel point que nous
est confie llaboration dun nouveau projet dont les concepts sont proches du ntre,
malistedecadeauxpournol. Raphal se voit offrir la lourde tche den mettre en place
les briques de base.
Raphal se dit quon la peut-tre un peu tromp sur la marchandise,
lorsquil dcouvre le planning du projet. Les dlais de ralisation sont plutt
optimistes, et ladoption de Scrum1 pour conduire cette preuve ne suffira
probablement pas faire des miracles si on vous vend les mthodes agiles sur ce seul
critre, mfiez-vous ! Toujours est-il quil va falloir mettre les bouches doubles pour
lancer ce projet en un temps record.
Mutualiser
Une solution intelligente consiste mutualiser nos outils et nos bonnes pratiques. Via le
mcanisme dhritage du POM, nous pouvons partager un POM parent commun dans
lequel seront remonts les dclarations de plugins, de versions de dpendances et les
autres paramtres applicables nos deux projets. De la mme faon, nos classes
peuvent tre dplaces dans un projet indpendant, dont nous partagerons le dveloppement.
1. Vous ne connaissez pas la mthode agile Scrum (http://fr.wikipedia.org/wiki/Scrum) ? Renseignez-vous vite auprs de votre JUG local pour quil organise une soire ddie :).
224
Partie III
ASTUCE
Llment <dependencyManagement> permet de dclarer de manire globale les versions
utilises pour les dpendances. Un projet qui hrite de dependencyManagement nest
affect daucune dpendance particulire ; par contre, sil dclare une dpendance sur cette
liste sans prciser de version ou en utilisant une autre version, celle du dependencyManagement prdomine.
Cest un bon moyen pour mutualiser une liste de dpendances dont le fonctionnement a t
valid et pour viter chacun de chercher quelle version dEHCache est compatible avec
hibernate-entitymanager x.y.z.
Il en est de mme avec les plugins via llment pluginManagement.
Qui paye ?
Dans un monde parfait, cette solution serait optimale : une seule source, un dveloppement profitant de lattention de tous pour un meilleur rsultat. Cest ce quessaie
de faire la fondation Apache pour ses propres projets en partageant un POM parent
(relativement simple) avec des informations communes comme la licence, les
dpts, les listes de discussion. Elle fait de mme pour le code travers le projet
commons.apache.org. Le rsultat est encourageant sans tre prodigieux.
Dans un monde dentreprise, cette solution est surtout source de conflits : qui assure
la maintenance des composants communs ? Qui dcide des volutions de ce composant ? Sur quel budget ? Qui supporte les tests de non-rgression lorsquun composant mutualis volue, alors que le projet qui lutilise na aucune volution en cours
qui pourrait (discrtement) en absorber le cot ? Sauf avoir une volont officielle
et finance de supporter cette mutualisation, cest malheureusement une voie sans
issue qui va surtout puiser la bonne volont des premiers contributeurs de ces
composants communs.
Partager un POM parent
Nous avons dj voqu lutilisation dun POM dentreprise, dans lequel sont places
toutes les dclarations propres linfrastructure et aux rgles de lentreprise. On va
pouvoir y rfrencer le serveur dintgration continue, le gestionnaire de dpt utilis
pour publier les artefacts. Il permet aussi de prconfigurer quelques plugins en fonction
de nos rgles de dveloppement. Les plugins lis aux outils de contrle qualit comme
Checkstyle, PMD ou FindBugs, peuvent ainsi tre associs aux rgles dont les dveloppeurs ont assimil lintrt. Le Listing 14.1 montre le POM parent que nous proposons
pour Geegol.
Chapitre 14
225
226
Partie III
Selon cette approche, Raphal commence par reproduire la structure de base de notre
projet et par copier nos fichiers POM ainsi que nos classes techniques, qui pourront
donner de bonnes pistes pour la ralisation. Rapidement, le travail devient titanesque
car il faut adapter ces copies : noms de package, groupId, artifactId et versions ne
correspondent pas. Le risque derreurs est grand, et obtenir un rsultat stable et complet
va prendre du temps !
Copier et mutualiser !
Raphal ne se laisse pas dmonter si facilement et propose une autre solution : faire un
copier-coller dont la phase dadaptation au nouveau projet est automatise ! Raphal est
en fait tomb sur la description du plugin archetype.
Un plugin qui cre des projets
Pour nous convaincre, il nous fait rapidement une dmonstration. Il se propose ainsi de
lancer un projet de plugin Maven, faisant ainsi rfrence au travail que nous avons d
accomplir au Chapitre 11. Nous avons tous en mmoire le temps quil nous a fallu pour
cela. Raphal tape donc une commande dans sa console :
mvn archetype:generate
Maven propose alors une liste impressionnante de composants, parmi lesquels Raphal
identifie un archtype mojo-archetype, quil slectionne. Maven lui demande de choisir pour son nouveau projet un groupId, un artifactId et une version. Aprs quelques
traces peu comprhensibles dans la console, Raphal nous lche un majestueux "et
voil". Le Listing 14.2 montre lexcution de cette commande. Nous avons limit la
liste des archtypes propose pour ne pas occuper deux pages supplmentaires.
Le Listing 14.3 montre la structure de fichiers rgnre.
Listing 14.2 : Gnration dun nouveau projet partir dun archtype
D:\>mvn archetype:generate
[INFO] Scanning for projects...
[INFO] Searching repository for plugin with prefix: archetype.
[INFO] -----------------------------------------------------------------------[INFO] Building Maven Default Project
[INFO]
Chapitre 14
227
08:55
08:55
08:55
08:55
<REP>
<REP>
<REP>
.
..
845 pom.xml
src
228
Partie III
D:\demo-maven-plugin>tree
D:.
src
main
java
com
geegol
maven
plugins
Pardon ? Tu rigoles ? Avec un petit sourire, Raphal propose de compiler son plugin et
de lexcuter. Un mvn install dans le rpertoire nouvellement apparu, puis un mvn
com.geegol.maven.plugins:demo-maven-plugin:1.0-SNAPSHOT:echo
et
nous
pouvons voir apparatre dans la console le rsultat simple mais tout de mme inespr :
[INFO] [demo:echo {execution: default-cli}]
Hello World from Maven!
Cest sr que ce plugin nest pas trs impressionnant pour ce quil fait, mais tout de
mme il ne nous aura pas cot beaucoup defforts et est totalement fonctionnel.
Raphal enchane donc avec lexplication.
Un archtype ?
Un archtype est la faon la Maven de faire de la mutualisation, avec un bonus considrable : son utilisateur peut, par la suite, faire voluer le code comme bon lui semble,
voire ne toucher rien pendant des annes sil nen voit pas lintrt. Il peut proposer
des volutions de larchtype sil a de bonnes ides ou des corrections apporter, mais
son code ne sera jamais impact sans son accord.
Contrairement une dpendance, pour laquelle on rcupre le rsultat final binaire, un
archtype fournit du code source, sur la base dun modle. Noms de packages, chemins
et mtadonnes Maven sont adapts au projet utilisateur. Le modle lui-mme est gr
comme un projet Maven part entire, dispose dune version et peut tre enrichi par
ceux qui ont du temps (et du budget) pour sen occuper. Les quipes peuvent proposer
de reporter dans le modle soit des corrections quelles ont faites pour viter dautres
de tomber dans les mmes embches, soit des enrichissements pour capitaliser sur le
travail ralis.
Construire ses propres archtypes
La structure dun archtype nest pas trs attirante a priori. Il sagit dun projet Maven
comprenant un nime descripteur XML et une srie de fichiers modles sous forme de
ressources. Le projet qui va en dcouler ne sera donc pas trs facilement accessible, et
ldition dun tel format pas trs simple.
Chapitre 14
229
230
Partie III
Chapitre 14
231
avanc et intgr que ce quil aurait pu obtenir en accumulant les conseils et fragments
de code piochs droite gauche.
Un support pour exprimenter
Dernier lment, un tel projet peut tre fdrateur au sein de lentreprise, en dmontrant
un savoir-faire et en servant de point dchange sur les technologies.
Au dmarrage de notre projet, sest pose la question du
choix dun framework web. Dans cette situation, chacun
tente dimposer son champion, dabord en mettant en
avant ses points forts, puis en dnigrant les concurrents lorsque les arguments commencent manquer, et au final par une petite guerre dinfluence et de dsinformation :
JSF cest naze,
GWT cest super lourd,
Struts 2 cest has been.
Bref, rien de vraiment constructif.
Pourquoi ne pas proposer dans lapplication blanche trois versions de la couche web
(sous forme de modules Maven ddis) ? Sur un exemple de base, nous pouvons
demander chaque framework de dmontrer sa plus-value et sa force.
Nous mettons en concurrence de manire constructive nos trois experts, qui fourniront
ainsi ce quils considrent comme ltat de lart de leur technologie prfre, accompagn des meilleurs exemples pour bien dmarrer. Plutt quune querelle de spcialistes
qui naboutirait rien de positif, nous pourrons ainsi proposer chaque nouveau projet
de faire son propre choix, en fonction des personnes disponibles, de leurs comptences,
des exigences du projet, etc.
Lorsque Franois revient nous voir pour nous fliciter du succs de
noubliepaslalistedescourses, il ne peut sempcher de nous taquiner en
ayant lair surpris de notre russite alors que nous navons pas expriment
plus avant la solution Flex, dont il est convaincu de la supriorit. Si nous navons pas
choisi cette voie aujourdhui, dautres le feront peut-tre sur une autre application, et les
quelques lignes dexemple de Franois intgres dans notre application blanche seront
dj un meilleur dbut quune page blanche.
Lapplication blanche peut ainsi servir de support pour exprimenter une technologie
directement dans le contexte de nos mthodes de travail. Faire fonctionner une application Flex, cest trs bien et sans doute facile avec le bon outillage. Russir en dvelopper une en bonne entente avec le reste de nos outils est une autre paire de manches.
232
Partie III
Chapitre 14
233
Lobsit des applications gnres. Une bonne partie du code rcupr par les
nouveaux projets nest pas utilise et reste en place comme code mort.
La complexit du modle. Trop de technologies sont mlanges et trop de choses sont
dmontrer en mme temps.
Mme si lapplication blanche est utile, il faut que son usage soit indiscutable dans le
contexte de votre entreprise, cest--dire que lon cre vritablement des projets similaires.
Il faut faire trs attention son dveloppement et sa maintenance pour quelle reste une
vitrine lgre et homogne des bonnes pratiques suivre.
Moralit : privilgier les petits exemples (et donc les petits archtypes) qui vont dmontrer
une problmatique donne.
Conclusion
Maven nous avait jusquici aids structurer notre projet et lui apporter rapidement de
nombreux outils qui en ont amlior le niveau gnral. Plutt que de laisser chaque
quipe refaire cette dmarche individuellement, nous offrons, grce aux archtypes la
capitalisation de notre exprience et, cela, de faon corporative. En poussant un peu
plus loin la logique du bon exemple, nous pouvons proposer aux projets futurs un
modle tout prt du meilleur de nos comptences, agrment de tous les exemples
ncessaires une mise en uvre rapide.
Dans un esprit de rduction de cots, damlioration de la productivit, dhomognit
des outils et de vlocit des dveloppements, lutilisation intelligente des archtypes est
clairement un lment dcisif. Elle fait de Maven une fois de plus un outil complet,
capable daider le dveloppeur Java pendant toutes les phases de son projet.
15
Avons-nous fait le bon choix ?
Le service Geegol Shopping List (dsormais disponible dans 27 langues, dont le breton)
est devenu un service phare du groupe. Projet exprimental au dpart, il est aujourdhui
un lment stratgique et les dcideurs du groupe veulent quelques garanties sur nos
mthodes de travail et notre outillage.
Maven a rpondu prsent pour chaque problme que nous avons rencontr. Si nous
sommes contents de notre choix, quen sera-t-il dans six mois, un an, puis dans cinq ?
Maven est un bon outil, mais nest pas pour autant le Saint-Graal et nest pas exempt de
dfauts.
Toute lquipe est donc runie pour dfendre ce choix face un comit dexperts qui ne
veut pas laisser un si beau projet reposer sur des outils non fiables, mal documents ou
dont lavenir est incertain. nous de nous montrer convaincants
236
Partie III
Les limites
Fabrice prend les devants et expose doffice les limites que nous avons
constates lors de lutilisation de Maven. Nous ne sommes pas face des
dbutants prts croire que Maven est la solution tout, autant jouer francjeu pour dsamorcer ce sujet ds le dbut.
Maven nest pas loutil magique qui va traiter tous nos problmes avant mme quils
narrivent si vous cherchez ce genre de solution, essayez lannotation @Abracadabra
dans votre code. Comme tout outil, il a ses forces mais aussi ses faiblesses et ses limites, et
il faut apprendre faire avec et les contourner intelligemment.
Points faibles
Il y a une critique, en particulier, qui vous a probablement dj titill : la syntaxe XML
inutilement verbeuse. Lintgration dans les IDE tend gommer ce dtail, mais il est
nanmoins bien prsent ds quon sattaque configurer un gros plugin comme Cargo
(voir Chapitre 8).
Quest-ce qui empche de modifier ce format POM pour le rendre plus compact, ou lui
ajouter des fonctionnalits ? Le code qui analyse ces fichiers XML est actuellement li
une version de Maven. Si un nouveau Maven sortait avec un format POM plus souple
ou intgrant une nouvelle fonctionnalit, il ne serait exploitable que par les utilisateurs
de cette nouvelle version de Maven. Au sein dune quipe de dveloppement, cela ne
serait pas un gros problme ; la difficult concerne les POM dploys par des projets
dans un dpt dartefacts, en particulier les projets open-source qui dploient sur
central. Leur utilisation ne serait alors possible que pour les utilisateurs du nouveau
Maven. Une prise en otage inacceptable !
Une deuxime limite de Maven concerne son fonctionnement en mode
multimodule, en particulier lorsquon exploite lhritage naturel : la
construction du projet POM parent doit se terminer avant que celle de ses
modules ne commence, afin quils puissent y faire rfrence. Il nest donc pas possible
dintgrer dans notre projet parent un plugin qui sexcuterait aprs la construction des
modules. Ce problme, Stphane la rencontr et contourn au Chapitre 13. Il peut
sembler anecdotique mais sa correction complte ncessite une refonte assez profonde
de Maven et de sa gestion du cycle de vie.
Un autre souci concerne les expressions, qui permettent de mutualiser des
numros de version comme dans lexemple ci-aprs :
<groupId>org.springframework</groupId>
<artifactId>spring-jms</artifactId>
<version>${spring.version}</version>
Chapitre 15
237
En utilisant systmatiquement cette proprit, nous pouvons tre srs que toutes nos
rfrences aux diffrents modules de spring utilisent une mme version cohrente, cest
donc bien pratique. Cependant, la proprit spring.version peut tre dclare ailleurs
dans le POM, mais aussi dans son parent, dans un profil, dans le fichier settings de
lutilisateur ou via la ligne de commande. Si elle est dploye telle quelle, comment
pouvons-nous tre srs quelle sera interprte lidentique dans un contexte trs diffrent ? En tant que responsable de notre livrable, Emmanuel a d se battre contre les
comportements qui dpendent de lenvironnement. Une construction de projet fiable
doit tre totalement reproductible.
La liste est encore longue des fonctionnalits manquantes, mal fichues, des bogues et
autres anomalies, et peu sont simples traiter
Sortons des limites lies au fonctionnement propre de Maven et intressons-nous la
norme OSGi qui connat un intrt croissant. Celle-ci accompagne une archive Java (un
bundle en terminologie OSGi) de mtadonnes dans un format propre, mais qui ressemblent
beaucoup aux concepts de dpendances de Maven.
Comment viter de dupliquer linformation ou, du moins, comment assurer la cohrence entre ces deux mondes ? Mme constat pour la norme Java modules qui fait
lobjet dune JSR et devrait tre intgre Java 7 (JSR-277). Comment Maven grerat-il ces nouveaux formats qui viennent marcher sur les plates-bandes de la gestion des
dpendances, en particulier le standard OSGi dont lordre de rsolution des conflits
nest pas exactement quivalent ?
Les plugins
Olivier signale galement la difficult pour identifier un plugin qui rponde
un besoin prcis et pour en qualifier la prennit. Or, Maven ne vit que par
ses nombreux plugins. Les besoins prcis sont soit une intgration dune
nouvelle technologie dans le build (comme GWT), soit une optimisation du build
propre un projet (comme compiler, dployer sur un serveur Tomcat tout en modifiant
sa configuration).
Le projet Apache Maven nhberge officiellement quun nombre rduit de ces plugins,
utiliss pour sa propre construction ou pour des besoins fondamentaux du dveloppement Java. Il sensuit que les plugins, qui sont finalement llment principal manipul
par lutilisateur final, sont plus ou moins laisss dans la nature, attendant le bon vouloir
dune communaut htroclite. Le projet Mojo encourage un regroupement visant
donner ces plugins un cadre et une culture communautaire, mais le dveloppement
reste peu structur et dpend du temps libre ou des intrts des dveloppeurs impliqus.
De nombreux plugins peuvent ainsi rester des annes dans le bac sable, zone de test
238
Partie III
permettant de faire natre de nouvelles ides, sans passer un tat stable qui leur donnerait
une plus grande crdibilit.
Par ailleurs, de nombreux dveloppeurs peuvent tre tents de crer leur propre
plugin en dehors de la communaut officielle Maven, et les hberger sur SourceForge, GoogleCode ou en interne dans leur entreprise. Ces efforts non coordonns
peuvent encourager une certaine crativit mais laissent surtout passer loccasion de
construire une solution plus viable avec un accueil plus large par la communaut des
utilisateurs.
De manire plus gnrale, lutilisateur qui ne trouve le plugin adquat pour un besoin
donn ni dans ceux de Maven, ni sur la liste des plugins stables de Mojo, est confront
un choix dlicat :
m
se laisser tenter par un plugin du bac sable Mojo, en esprant que son dveloppement soit encore actif, et sans aucune garantie de voir un jour une version stable en
sortir ;
chercher en dehors de ces sources officielles un plugin adapt, mais avec le risque
de ne trouver que des solutions partielles sans support et mconnues de la communaut ;
se lancer dans une solution interne, dont il faudra supporter le cot de dveloppement et qui ne bnficiera pas de lenrichissement dune communaut de centaines
dutilisateurs.
INFO
Prcisons que le projet Mojo est ouvert aux contributions et toujours enthousiaste
accueillir des dveloppeurs qui veulent prendre en charge un plugin labandon ou proposer leur propre travail la communaut. Cest en tout cas la politique que nous dfendons,
mme si nous ne sommes pas seuls bord. Nhsitez pas venir nous parler de vos projets et
envies sur la liste de diffusion : user@mojo.codehaus.org.
Le support
Lutilisation de Maven est simple si on suit ses conventions et quon dispose
des bons plugins ; elle peut devenir assez vite dlicate, si on na pas les bons
rflexes, voire totalement insurmontable, si on tente de plier Maven des
utilisations pour lesquelles il na pas t prvu. Le support est donc un lment cl de
son utilisation, et Vincent ne manque pas de le souligner (la question allait venir dellemme de toute faon). Il ne fait aucun doute que vous y aurez recours un moment ou
un autre mme en ayant lu avec attention les pages de ce livre.
Chapitre 15
239
1. http://opensourcestrategies.blogspot.com/2005/09/how-to-get-support-from-opensource.html.
2. Accessible sans client IRC par linterface web http://irc.codehaus.org/.
3. http://www.developpez.net/forums/f319/java/edi-outils-java/maven/.
4. http://java.developpez.com/faq/maven/.
240
Partie III
Le cot de Maven
Herv rebondit sur la question du support en voquant le prix de revient
de Maven sur un projet. Maven est un projet libre, tlchargeable et utilisable gratuitement. Son cot dutilisation nest cependant pas nul,
comme tout projet open-source. Le simple fait que vous ayez ce livre entre les mains
est dj un lment de rponse : il nest pas si facile utiliser et ncessite un certain
apprentissage. Il ne sapplique pas nimporte quel projet et sans un certain effort
dorganisation. Il ncessite donc un minimum dexprience. Les socits de services
ne sy sont dailleurs pas trompes et vendent consultants et formations autour de ce
sujet.
Comme de nombreux outils, Maven cote bien plus cher par la formation quil induit
que par son prix dachat (qui est particulirement attrayant dans le cas dun projet
libre). Sa documentation en ligne est perfectible mais elle est paule par de nombreuses autres sources. Ce livre fait partie de cet effort et vient complter les livres Builds
with Maven5 et Maven the definitive guide, bible de 500 pages qui prsente tous les
aspects de Maven, sans compter les innombrables blogs, articles, forums et tutoriels qui
dcrivent des points plus spcifiques de son utilisation.
La concurrence
Aprs cette autocritique, Vincent prend en main la contre-attaque : quelle
autre solution avons-nous pour la gestion de notre projet ? Nous avons
voqu Ant au Chapitre 1, mais la concurrence laquelle Maven sexpose
ne sarrte pas l. Certains outils ont dailleurs capitalis sur les bonnes pratiques reconnues de Maven et ont tent de crer une nouvelle solution plus productive sur cette base.
Cette mancipation, bnfique tous, est encourage par les dveloppeurs de Maven,
mme sils acceptent forcment assez mal les critiques si elles ne sont pas enrobes par
la politesse et les justifications ncessaires. Un outil, en particulier open-source, ne peut
pas tenir ses utilisateurs en otage. Il est contraint lexcellence pour occuper le dessus
du panier. Les critiques, plus ou moins constructives ou honntes, sont invitables mais
doivent toujours tre considres avec attention.
Maven bon partout ?
Nous avons tent au cours des chapitres prcdents de vous dmontrer en quoi lapproche propose par Maven est dun niveau suprieur au simple script de construction de
5. http://www.maestrodev.com/better-build-maven.
Chapitre 15
241
projet. Il faut cependant admettre que Maven nest pas bon partout et mal adapt
certains projets.
Maven part du principe que 99 % des projets ont des besoins comparables et peuvent
sappuyer sur les mmes outils et bonnes pratiques sils acceptent des conventions
communes. Il reste cependant 1 % de projets qui ont des besoins vraiment trs spcifiques tout le monde dira que son projet est diffrent des autres, mais soyons honntes,
part quelques cas extrmes, nous faisons tous plus ou moins la mme chose. Nous
pourrions comparer la standardisation de la construction celle du dmarrage : qui de
nous a besoin dune JVM customise avec 12 paramtres en " -XX:" pour lancer son
application ?
Google Web Toolkit rentre dans les projets "spcifiques". La compilation des sources
doit marier du code natif pour Windows, Linux et Mac OS, linclusion de code source
Java dans larchive JAR, et bien dautres subtilits. Construire un tel projet avec Maven
serait possible, mais il faudrait alors considrer la plus-value quil apporterait aux dveloppeurs. Le mcanisme de test de ce projet est ultra-spcifique, les artefacts construits
si, au final, ils sont des archives JAR sont composs dlments peu courants. La
configuration ncessaire dans Maven pour obtenir un rsultat convaincant serait significative. Ce projet ne rentre pas dans le cadre des 99 %.
Spring 2 a lui aussi choisi de ne pas utiliser Maven pour sa construction. Pour ce projet
devant mixer la compilation de classes destines Java 1.4 et Java 5, en plus de divers
raffinements dont la compatibilit OSGi, il faut bien reconnatre que Maven se serait
assez mal prt au jeu.
Enfin, dautres projets de dveloppement bass sur des outils propritaires ou non
(pensons Liferay ou Alfresco) imposent gnralement leurs propres scripts de compilation et donc ces types de projets rentrent, l encore, dans le 1 %.
Maintenant, nous ne sommes pas nombreux travailler sur des projets aussi particuliers. Cela ninterdit pas de regarder ce qui se fait ailleurs pour dterminer si Maven est
le meilleur choix. Il est intressant de noter que Spring 3 spare ses packages principaux en modules ddis et intgre mme un fichier POM exprimental 6.
This POM cannot be used to build Spring; it is a work in progress and should only be
used as part of a Maven repository upload bundle using artifacts created by the
spring build system.
242
Partie III
Ant et Ivy
Nous avons dj parl dApache Ant, qui a t longtemps le standard de fait pour la
construction de projets en Java. Ivy est un projet qui lui apporte une gestion des dpendances trs proche de ce que Maven propose Ivy sait dailleurs exploiter les POM de
Maven et ses dpts de bibliothques. Le couple Ant + Ivy permet donc de faire globalement la mme chose que Maven pour ce qui est de la gestion des bibliothques.
Par contre, cela napporte rien en termes dhomognit des projets, de conventions
dorganisation du code ou de rutilisation des scripts Ant. Ivy apporte Ant une fonctionnalit cl de Maven mais ne change en rien sa philosophie gnrale. La comparaison entre Ant et Maven ne doit pas se faire en comptant le nombre de lignes de XML
ncessaires pour compiler des classes, mais en fonction de lesprit gnral de loutil et
de ce quil apporte ou impose sur un projet.
On peut faire le choix dAnt, de la libert quapporte un langage de script pour faire
peu prs tout ce quon veut. Il ne faudra alors pas stonner que cette libert ait un prix
en maintenance et en volutivit du projet.
EasyAnt
EasyAnt7, comme son nom le suggre, vise simplifier lutilisation dAnt. Il propose
une surcouche qui intgre Ivy et un certain nombre de conventions, permettant de
passer des commandes de construction sans avoir tablir une configuration rptitive
dun projet lautre. Un mcanisme de plugins permet de prparer des fragments de
script Ant pour tre partags entre projets.
Lapproche est intressante dans le sens o elle rejoint le constat qui est lorigine de
Maven : des projets comparables doivent sans cesse rcrire la mme configuration,
alors quils vont drouler globalement les mmes procdures. EasyAnt nest cependant
pas aussi easy quil le prtend si lon considre quil exploite les namespace dans un
langage de script XML, ce qui nest pas dune grande lisibilit pour le dveloppeur
novice. De ce point de vue, Gradle est nettement plus innovant.
Gradle
Gradle8 sappuie lui aussi sur Ant et Ivy, et met en place un esprit de construction par
conventions. Bas sur Groovy plutt que XML, un script Gradle manipule des tches
Ant traditionnelles qui sont ses briques de base. Groovy est mis contribution pour
7. http://www.easyant.org/.
8. http://www.gradle.org/.
Chapitre 15
243
Nous ne rentrerons pas plus en dtail dans Gradle, dont la documentation en ligne 9 est
trs complte si cette alternative vous intresse.
En tant quanciens de la communaut Maven, autant EasyAnt que Gradle nous rappellent normment une vieille connaissance : Maven 1.
9. http://www.gradle.org/userguide.html.
244
Partie III
Maven 1
Maven 1 avait pour objectif de fournir au-dessus dAnt une gestion de dpendances
(Ivy nexistant alors pas encore) et une approche par conventions. Il utilisait des fichiers
de script XML bass sur Ant et sur un langage de programmation XML (jelly). Les
tches les plus courantes taient regroupes dans des plugins, quon pouvait importer et
invoquer dans les projets.
Maven 1 a eu ses heures de succs en dmontrant les apports de la standardisation, puis
a montr ses limites quand les scripts des plugins ont commenc se complexifier pour
viter des effets de bord et des interactions mutuelles. Ce demi-chec a t lorigine
de Maven 2, construit sur un modle nettement plus robuste.
La syntaxe de Gradle est compacte, claire et trs spcialise grce Groovy et sa
capacit naturelle construire des DSL. Le concept mis en uvre dans EasyAnt comme
dans Gradle nous semble par contre obsolte, car nous avons dj explor cette voie et
rencontr des obstacles bien dlicats franchir. Si Gradle est construit sur des outils
modernes, son principe de base est limit.
Buildr
Apache aime bien dvelopper des outils de build ! En plus de Maven et dAnt, il existe
aussi le projet Buildr10, se positionnant dans lorganisation des projets comme Maven.
Il utilise le langage Ruby au lieu du XML, les conventions de Maven et sintgre avec
Ant et les dpts Maven.
Nous ne dtaillerons pas ce dernier candidat, sachant que nous en avons laiss dautres
en retrait, nombreux, qui se proclament tous aussi rvolutionnaires et intuitifs les uns
que les autres. Rappelons simplement lun des reproches le plus souvent faits Maven :
labsence dune bonne intgration sous Eclipse. Si on considre les autres solutions,
lintgration est quasi inexistante ou limite au lancement des tches de construction.
Un outil reconnu
Il existe donc de nombreuses concurrents face Maven, alors pourquoi le choisir a
priori plutt quune autre ? Un lment de rponse simple se trouve dans la maturit de
loutil et la taille de sa communaut, ou plutt dans son niveau de pntration en entreprise, comme toute valuation de projet open-source. Il sera plus facile de trouver rapidement des personnes comptentes sur un outil largement utilis, mme sil est
imparfait, que de galrer avec un bijou technologique que trois personnes au monde
savent faire fonctionner.
10. http://buildr.apache.org/.
Chapitre 15
245
La communaut
Arnaud poursuit le travail dvanglisation en dmontrant que nous ne
sommes pas de dangereux geeks qui ont mis sur un outil qui finira aux
oubliettes ds que la mode sera passe.
Maven ne vit quau travers de la communaut de ses utilisateurs, qui assurent lessentiel
du support de loutil. Les dveloppeurs ne sont plus eux-mmes mis systmatiquement
contribution vu la trs large base dutilisateurs avancs qui participent activement aux
discussions en ligne. La Figure 15.1 prsente le nombre dutilisateurs de la liste
user@maven.apache.org ainsi que le nombre de messages par jour. Cette liste est trs
active et rpond aux nombreuses questions de toute nature que les utilisateurs de tous
niveaux formulent, parfois dans un anglais assez approximatif (cest un moyen simple
pour reconnatre des collgues francophones).
Nombre
dinscrits
Nombre de
messages
Figure 15.1
Trafic de la liste users@maven.apache.org.
Autre indicateur, le trafic sur le site web maven.apache.org. Les Figures 15.2 et 15.3
affichent le compte rendu des visites pendant un mois, ce qui donne une bonne ide du
nombre dutilisateurs de Maven amens configurer leurs plugins (le site web tant la
principale source dinformation sur cet aspect). La Figure 15.4 indique le nombre de
tlchargements de Maven au cours de lanne, toutes versions confondues. Ici encore,
les chiffres dmontrent une trs large communaut.
Si vous choisissez Maven, vous ne serez donc pas tout seul et vous trouverez rapidement des collgues utilisant le mme outil. Nous avons peut-tre tous tort par rapport
une autre solution parfaite ou presque, mais au moins nous pouvons nous serrer les
coudes et avancer ensemble.
246
Figure 15.2
Origine gographique des visiteurs de maven.apache.org.
Figure 15.3
Trafic sur le site web maven.apache.org.
Figure 15.4
Tlchargements mensuels de Maven sur un an, toutes versions confondues.
Partie III
Chapitre 15
247
Lquipe de dveloppement
Arnaud poursuit en prsentant le cur du projet Apache Maven, ceux qui le dveloppement et dont nous dpendons au final.
Maven, cest aujourdhui 55 dveloppeurs, dont une bonne vingtaine trs actifs en
2009, et une trs longue liste de contributeurs qui rapportent des bogues, proposent des
correctifs ou discutent des volutions. Maven, cest surtout un trs large choix de
plugins qui impliquent tout autant de dveloppeurs de toutes origines.
Cette quipe motive est lorigine de plusieurs ouvrages, dont celui que vous tenez
entre les mains, auquel vous pouvez ajouter le Definitive Guide et Better Build with
Maven, tous deux disponibles en ligne gratuitement, et Apache Maven 2 Effective
Implementations, propos en ligne, chapitre par chapitre, au fur et mesure de sa
rdaction.
Limit au monde francophone, Maven cest encore dix membres bien de chez nous qui
ont particip cet ouvrage en corrigeant nos erreurs. Cest aussi une volont de
communiquer avec les utilisateurs, comme la dmontre notre prsence active dans les
Java User Groups.
Maven est donc un projet trs dynamique, et si les versions ne senchanent pas aussi
vite quon pourrait le dsirer, cest surtout parce que la qualit de nos livrables est
constamment amliore et quune politique trs scrupuleuse (et trs complexe) de
compatibilit avec lexistant est suivie.
Ladoption en entreprise
Votre Honneur, jappelle la barre notre premier tmoin : Jrme.
Jrme a test Maven suite nos recommandations pour lancer une nouvelle
application et former son quipe. Il est en quelque sorte notre cobaye pour
valider ladoption de Maven sur dautres projets.
Pourquoi Maven russit-il une perce en entreprise ? Nous lavons vu au cours des
chapitres qui ont prcd, Maven est un fdrateur doutils. La mme ligne de
commande permet de construire nimporte quel projet Maven bien configur.
Quel chef de projet ne rve pas de pouvoir affecter un nouveau dveloppeur dans
lurgence sans devoir perdre dans le mme temps une ressource, le temps de lui expliquer toutes les ficelles du projet ? Avec des projets correctement construits avec Maven,
le passage dun projet un autre se rsume un checkout depuis le gestionnaire de
code source. Jrme abonde dans ce sens en expliquant comment nous avons pu lui
apporter une aide rapide en jetant juste un rapide coup dil sur son projet. Via une
248
Partie III
structure comparable, il est plus facile de sapproprier en peu de temps un projet dvelopp ailleurs.
Jrme souligne ensuite les bonnes pratiques que vhicule Maven : une gestion stricte
des dpendances, des tests qui font corps avec le dveloppement et non comme tche
part, lintgration des outils de qualit logicielle, le support de lintgration continue,
etc. Pour avoir trop souvent pilot des projets peu scrupuleux et raliss sans filet, reposant sur les paules de quelques personnes, il apprcie davoir enfin un cadre solide et
homogne.
En entreprise, Maven est un lment cl de ce socle quon appelle software factory, qui
vise proposer une solution industrialise, reproductible et stabilise pour les dveloppements logiciels, sortant de plusieurs dcennies de bricolage. Jrme, en sinspirant de
notre exemple, est en train de mettre en uvre le mme type doutillage et bnficie des
infrastructures que nous avons dj mises en place : gestionnaire du dpt dartefacts,
serveur dintgration continue.
Lavenir de Maven
Mission impossible ?
Bonjour, Monsieur Phelps. Votre mission, si vous lacceptez, est de prsenter nos
lecteurs lavenir de Maven. Comme tout projet open-source, son dveloppement
nest guid par aucun plan grav dans le marbre et toute annonce prliminaire peut
tre contredite par les faits. Pour viter nos lecteurs de se btir une opinion sur
des informations errones, prenez soin dannoter les donnes les plus spculatives de votre
logo Impossible Mission Force.
Si vous ou lun de vos agents tait captur ou tu, les auteurs nieraient avoir eu connaissance
de vos agissements. Bonne chance, Jim
Cet encadr sautodtruira dans dix secondes PChittttttt !
Que va devenir Maven ? Son dveloppement suit, en ralit, deux voies parallles :
m
Maven 3 a longtemps t appel Maven 2.1, mais son dveloppement prend nettement plus de temps que prvu et les changements internes sont suffisamment radicaux pour justifier un saut de version. Le contenu exact de cette nouvelle version
nest pas statu et dpendra de ce que les dveloppeurs sont prts payer en sueur et
en huile de coude.
Chapitre 15
249
Maven 2.x
Maven 2 suit son dveloppement par correction des problmes les plus paralysants et
par introduction progressive de nouvelles fonctionnalits. Avec le changement de la
branche de dveloppement principale en "Maven 3", les numros de version ont t
librs pour tablir un plan raliste sur le projet, donnant un regain dintrt aux dveloppeurs. Cela permet plus clairement de limiter les versions correctives (2.0.9, 2.0.10)
de simples corrections danomalies et de rserver les nouvelles fonctionnalits aux
versions mineures (2.1, 2.2).
Maven 2.0.x
End of life nattendez rien de nouveau autour de Maven 2.0.x, sauf une ventuelle
correction si un gros problme venait tre dtect.
Maven 2.1
Maven 2.1 a t la premire version profiter de cet lan. Les nouvelles fonctionnalits
quil apporte peuvent sembler superficielles mais limportance est avant tout le redmarrage de cette branche de dveloppement en parallle de Maven 3. Maven 2.1
introduit :
m
Sans oublier une nette amlioration des performances sur linitialisation de Maven
dans un contexte avec de nombreux modules.
250
Partie III
Maven 2.2
Cest tout ? a fait un peu maigre, mme pour une version mineure. On dirait plutt une
petite version corrective ! La raison principale de ce changement de version est que
Maven 2.2 ncessite dsormais Java 5. La compatibilit avec Java 1.4 a t longtemps
conserve pour ne pas dranger les utilisateurs, Java 5 est ncessaire pour corriger
certains bogues. Cela ninterdit pas de construire des projets pour Java 1.4, voire des
versions antrieures, mais le poste de dveloppement doit disposer dun JDK 5 pour
excuter Maven lui-mme.
Maven 2.3
La version suivante de Maven 2 est logiquement une 2.3. Son contenu exact nest pas
dfini lheure o nous rdigeons ces lignes, mais limportant est quune dynamique
soit enfin en place pour avoir rgulirement de nouvelles versions de Maven 2 et redynamiser les dveloppements.
le support dvolutions dans le modle POM et son format XML, sans briser pour
autant la compatibilit des dpts dartefacts avec les versions plus anciennes de
Maven ;
Chapitre 15
251
Maven 3.x
Maven 3 a longtemps t connu sous le nom de Maven 2.1. Son dveloppement
correspond une refonte profonde du cur de Maven, travaux importants mens de
manire trs active par lquipe de Sonatype, socit fonde par Jason Van Zyl,
dveloppeur initial de Maven. Cette reprise lourde du code a, dans un premier temps,
paralys les volutions sur Maven 2.0 car tout le monde attendait plus ou moins la
suite. Les choses ne vont cependant jamais assez vite et lex-Maven 2.1 a t
renomm Maven 3.x pour bien indiquer la rupture et laisser de la place pour de
nouvelles versions de Maven 2.
Enjeux
Lun des plus gros travaux sur Maven 3, et qui explique en grande partie son retard, est
la compatibilit avec lexistant. Un ensemble de tests dintgration a t crit pour
mettre en scne Maven confront la plupart de ses cas dutilisation. Projets simples,
multimodules, plugins plus ou moins complexes, sont ainsi excuts en boucle par un
harnais de scurit antirgression de plus de 350 tests. Ce nest pas une garantie absolue,
mais cest une scurit que peu de projets peuvent proposer.
252
Partie III
uvre soit termin pour prendre part au jeu de lExtreme makeover : Maven edition11.
Ds que le cur de Maven 3 sera stabilis, on peut sattendre une bascule rapide des
dveloppeurs Maven vers ce socle rnov.
Quoi de neuf ?
Le changement le plus notable dans Maven 3 est la possibilit de lintgrer dans un
autre outil. Des prversions sont ainsi utilises par toutes les solutions dintgration
dans un IDE. Pour continuer dans ce sens, Maven 3 gre la notion de construction
incrmentale du projet, ce qui permet de reprendre la construction partir dune tape
intermdiaire pour plus de ractivit. Pensez, en particulier, au fonctionnement de votre
IDE lorsque vous ditez un fichier source. Celui-ci ne va pas reconstruire tout lespace
de travail en effaant tout lexistant, mais travailler par diffrence avec ce qui tait dj
construit et juste recompiler ce qui est impact par votre modification. Avec la gestion
de la construction incrmentale dans Maven lui-mme, il sera possible de laisser lIDE
faire certaines de ces tches tout en exploitant les plugins Maven pour dautres, comme
cest dj le cas pour la compilation du code source. Cette volution, qui porte galement sur plusieurs plugins, permettra de combler les manques que nous avons identifis
au Chapitre 9.
Maven 3 vise galement fournir une structure plus robuste et plus comprhensible. Le
code a t fondamentalement revu et dpoussir des nombreuses annes de dveloppement de Maven 2. Le rsultat doit tre plus concis et plus lisible, lide tant de fournir
une base comprhensible pour entraner plus de dveloppeurs dans le support et le
dveloppement de Maven. Les tests dintgration se montrent ici indispensables pour
assurer le fonctionnement lidentique.
11. Si vous ne connaissez pas, regardez au moins une fois : Les Maons du c?ur (Extreme Makeover
Home Edition en VO), a vous donnera une ide des travaux en cours.
Chapitre 15
253
Certaines fonctions internes tant repenses ou remplaces, il faut sassurer que les trs
nombreux plugins existants y trouveront encore leur compte, quitte rediriger les
appels de mthode vers le nouveau code. Dans ce but, des environnements spars sont
prvus pour lexcution des plugins bass sur lAPI Maven 2.
Les nouveaux plugins crits pour Maven 3 pourront bien sr exploiter
la nouvelle API de programmation directement. Celle-ci fournit aux
plugins une bien meilleure vision de la construction en cours et du
projet considr. Des points dextension sont proposs, dans lesprit de
ceux utiliss par Eclipse ou OSGi. En particulier, un plugin Maven 3 peut proposer des
paramtres de type out, cest--dire destins enrichir le contexte du projet de nouvelles
mtadonnes.
La gestion du cycle de vie est, elle aussi, revue. Ce dernier devient consultable avant
excution, ce qui est indispensable pour lintgration dans les IDE, qui peuvent ainsi
dterminer quel plugin va tre excut et ajuster le comportement de la construction
incrmentale en consquence. La nouvelle API permet lexcution de code avant et
aprs le cycle de vie, remplaant la notion pineuse de plugin aggregator qui sexcute
dans Maven 2 plusieurs niveaux dans le cycle de vie dun projet multimodule.
Le socle technique de Maven 3 volue galement. Plexus, conteneur
dinjection de dpendance utilis par Maven 2, est ainsi dlaiss au
profit dune implmentation conforme la norme JSR 330 Dependency Injection. Lutilisation dune norme devrait rendre le code
plus abordable de nouveaux dveloppeurs (Plexus tant de ce point de vue un frein)
et, potentiellement, libre Maven de son adhrence un outil particulier. Google Guice,
lorigine de cette norme, est le meilleur candidat pour devenir le conteneur de
Maven 3, mais il pourrait tre remplac au besoin par une solution alternative. Par
ailleurs, en se basant sur Java 5, Maven 3 met au placard les balises Javadoc et introduit
des annotations.
La gestion des dpendances a t totalement rcrite pour tre plus prvisible et plus
volutive. Elle est dsormais indpendante du cur de Maven, au sein du projet
Mercury. Laccent a t mis sur la compatibilit avec OSGi concernant la dfinition des
versions et la gestion des conflits. Laccs aux dpts a t rcrit par lquipe du
moteur de servlet Jetty, vritables experts du protocole HTTP. La rsolution des conflits
de versions entre dpendances est dsormais plus claire et peut tre remplace par
lutilisateur au besoin. Ntant plus directement li Maven, Mercury pourrait tre
exploit par dautres outils pour la gestion des dpendances et des mtadonnes ou des
dpts de bibliothques.
254
Partie III
La faon dont le modle du projet (le fameux POM) est construit partir des fichiers
pom.xml et de leurs parents est clairement tablie et documente. Aussi surprenant que
cela puisse paratre, cest un aspect de Maven 2 qui est assez peu clair, et donc sujet
de dangereuses rgressions lorsquon veut y intgrer des modifications. La tentative
dune version 2.0.11 y a en particulier laiss des plumes.
Cette gestion clarifie et revue permet Maven 3 de supporter lhritage dun parent
sans prcision de sa version, ce qui vite de rpter dans un projet multimodule le
numro de version commun du projet. Il est aussi possible dimporter des parties de
POM, en ralisant des mixins pour reprendre dun autre projet la gestion des dpendances ou la configuration dune srie de plugins. Plutt que dhriter dun POM, on
pourra ainsi travailler par composition.
Et la suite ?
Mme sil est encore bien trop tt pour savoir de quoi lavenir sera fait, quelques fonctionnalits de Maven 3.1 sont dj trs attendues et, notamment, la possibilit pour le
POM dutiliser un format alternatif. Nous avons vu que le format XML actuel est particulirement verbeux ; Maven 3.1 permettra dutiliser un format XML plus compact
(fond sur des attributs) comme le montre le Listing 15.1.
Chapitre 15
255
Quand ?
La question vidente qui vient lesprit aprs une telle publicit est : quand ?
Lex-Maven 2.1 a t promis il y a dj plus dun an, sans quon voie rien venir. Il a t
renomm Maven 3, et on attend encore avec impatience que toutes ses fonctionnalits
soient stabilises et proposes aux utilisateurs. Il existe dj des prversions, et votre
IDE prfr en intgre peut-tre une. De laveu mme de ses dveloppeurs, les versions
actuelles de Maven 3 sont des alpha, tout juste bonnes dmontrer la faisabilit du
concept ou contenter de purs geeks un peu masochistes.
Personne ne saventurera donc annoncer une date, dautant que le modle de fonctionnement de la fondation Apache, pour lequel la mise disposition dune version est
soumise un vote, peut faire mentir toute annonce anticipe. On peut juste noter que
ltat actuel des tests dintgration est encourageant pour remplacer Maven 2 par une
version viable, relativement court terme. Une version publique officielle de Maven 3
prendra cependant plus de temps afin de peaufiner chaque dtail. Cinq personnes
travaillent plein-temps sur Maven 3, aussi les choses avancent grands pas, mais
nesprez pas lannonce officielle dun Maven 3.0.0 General Availability avant fin
2010.
256
Partie III
La fondation Apache
Raphal se fait un plaisir en expliquant le monde open-source et les garanties
intrinsques quapporte ce modle.
Maven est lun des nombreux projets hbergs par la fondation Apache,
surtout connue pour son excellent serveur HTTP ( tel point quon parle souvent dun
serveur apache, sans plus de prcision). Cette fondation assure par son statut lindpendance des projets hbergs vis--vis dun diteur et encourage le dveloppement
communautaire.
Un projet Apache est conduit par un comit de pilotage, pour lequel chaque membre
dispose dun droit de veto sur les dcisions prises, et o chaque dcision majeure doit
tre soumise au vote et obtenir au moins trois avis favorables. Cette rgle de conduite
assure la stabilit des projets et le soutien de ses membres majeurs. Les autres membres
du projet, qui ne font pas partie du comit et ne disposent pas dun droit de veto,
peuvent exprimer leur avis librement lors des votes. Il est rare que la dcision finale ne
soit pas le reflet dun compromis accept par tous.
Maven sest dvelopp dans cet esprit, chaque grande dcision tant soumise la
communaut des dveloppeurs et refltant leurs choix communs. Au sein de la fondation Apache, il ny a donc pas de propritaire du projet, en dehors du comit dont les
membres ont des attaches trs varies.
Cest une distinction notable par rapport dautres projets open-source dont les dcisions ne sont pas si ouvertes. SpringFramework, par exemple, est un projet ouvert aux
suggestions de ses utilisateurs et dont le code est libre, mais dont le dveloppement est
gr par la socit SpringSource12. Lexcellente quipe de dveloppeurs que SpringSource a russi runir propose un outil de grande qualit, tandis que le soin apport
pour rpondre aux rapports danomalies et aux suggestions de la communaut dutilisateurs est exemplaire. Louverture de ce projet reste cependant un petit cran en dessous
de ce que peut proposer un logiciel hberg par la fondation Apache et soumis une
gestion communautaire multipartite.
Sonatype
Nicolas poursuit en constatant une certaine incrdulit de notre auditoire. Le
monde merveilleux de lopen-source tout gratuit, o des dveloppeursbisounours-bnvoles offrent leur temps et leur code la communaut, les
12. Entre la rdaction de ce chapitre et sa relecture, SpringSource a t rachet par VMWare. Les
choses vont tellement vite en informatique
Chapitre 15
257
laisse perplexes. Derrire Maven, comme partout, il y a des gens payer et des machines
qui tournent.
Vous aurez not dans les pages qui prcdent la trs forte adhrence entre le dveloppement de Maven et la socit Sonatype. Maven est en effet un projet complexe, englobant des solutions techniques trs spcifiques pensez, par exemple, la gestion de
chargeurs de classes isols pour chaque plugin, concept qui reste assez thorique pour
une grande majorit de dveloppeurs.
Parce que Maven est historiquement construit sur Plexus, conteneur dinjection de
dpendance comparable mais bien moins connu que Spring, le prix payer pour suivre
les dveloppements en cours est assez lourd. Les technologies engages sont nombreuses et ncessitent un gros investissement en temps. Lvolution du dveloppement est,
par ailleurs, essentiellement trace via le forum de dveloppement ; il est donc difficile
de se faire en peu de temps une ide prcise des tches en cours et de leur avancement.
Sonatype participe de manire trs active la vie de la communaut Maven. En plus
daffecter cinq personnes plein-temps au dveloppement de Maven, la socit met
sa disposition ses infrastructures rseau et dite librement le Definitive Guide. Si
Maven 3 avance, cest surtout grce au travail de fond de Sonatype sur le sujet.
Maven est cependant un projet de la fondation Apache, dont nous avons vu les rgles de
conduite, et, ce titre, on peut trouver choquant de le voir ml de si prs au nom dune
seule socit.
Maven + OSGi = Tycho
Nous avons voqu la difficult pour Maven sintgrer correctement au monde OSGi
sans ddoubler linformation. La rponse sincarne dans le projet Tycho. Celui-ci vise
fournir loutillage ncessaire pour faire de lOSGi partir dun projet Maven aussi bien
que pour faire du Maven partir de bundles OSGi. Ce pont entre les deux technologies
pourrait rapidement devenir un enjeu commercial.
Sonatype, lorigine de ce projet en marge de Maven, a cependant choisi den faire une
solution open-source. Bien sr, Sonatype y prend une longueur davance sur tout
concurrent qui voudrait occuper ce terrain, mais la dmarche doit tout de mme tre
souligne. De nombreuses autres socits, moins imprgnes par le modle opensource, nauraient pas suivi cette voie et auraient tent de monnayer leur comptence.
Quel intrt a Sonatype douvrir ainsi ses dveloppements ? Ses revenus proviennent de
son activit de support, de formation et de conseil autour de lutilisation de Maven,
ainsi que des licences de Nexus en version Professionnal quelle distribue. Comme
beaucoup de socits fondes sur un modle open-source, Sonatype doit donc
258
Partie III
sappuyer sur une base dutilisateurs aussi large que possible et sur une adoption
massive en entreprise. Le meilleur moyen dy arriver est de proposer un outil toujours
la pointe des technologies mergentes.
Proposer un outil purement propritaire pour marier Maven avec OSGi serait contreproductif. Une partie des utilisateurs et donc des clients potentiels se tournerait vers
des solutions libres, ventuellement moins bien intgres. Le monde Java est particulirement marqu par le modle open-source, et le seul argument financier ne suffit pas
expliquer cet engouement. Aller contre les attentes du public pour une socit comme
Sonatype serait comme couper la branche sur laquelle on est assis.
En dehors de cette considration purement stratgique, il ne faut pas non plus oublier
qui constitue lquipe de Sonatype. Vous avez affaire des gens techno-addicts, pas
des financiers. Des gens qui se passionnent pour le code et les nouveauts technologiques, et qui ne laisseraient personne le soin de coder leur place. Ces gens sont
imprgns par le modle open-source et nauraient pas lide de lancer un nouvel outil
en dehors de cet esprit. Ils sont au cur du projet quils ont construit et vu simposer,
rien ne leur ferait plus mal que de voir leur bb devenir une marchandise de plus.
Non, Sonatype nest pas seul !
Sonatype est la socit la plus visible dans lcosystme Maven parce quelle est dirige par le fondateur de Maven et quelle finance lhbergement dune partie de linfrastructure de dveloppement en particulier, le dpt dartefacts central et les gigaoctets
de trafic quil gnre.
Dire que Maven est dvelopp par Sonatype est cependant totalement faux. En particulier, la socit MaestroDev emploie quatre dveloppeurs Maven 13 dont deux membres
minents du comit de pilotage. Leur engagement en faveur du dveloppement de
Maven et dautres projets de la fondation Apache est tout aussi fort que celui de Sonatype.
Par ailleurs, lquipe de dveloppement de Maven ne se rsume pas ces quelques
personnes. Lquipe complte14 compte des individus dorigines trs varies et rattachs des employeurs de toutes sortes. Pris individuellement, ils sont peu visibles,
mais, comme pour tout projet open-source, cest ensemble quils ont donn vie au
projet Maven. Leur avis compte autant lors des discussions sur les orientations donner
au projet.
13. http://www.maestrodev.com/who-we-are.
14. http://maven.apache.org/team-list.html.
Chapitre 15
259
Maven est dvelopp sous licence libre Apache. Quoi quil arrive, personne ne
pourra vous rclamer de droits si vous prenez ce code pour en faire ce que bon vous
semble. En particulier, si une socit investissait massivement dans le dveloppement pour crer un Maven Professional payant (ce que la licence Apache ninterdirait pas), cela ne ferait que vous priver des fonctionnalits ajoutes la version libre.
Si la diffrence est rellement une plus-value significative, le prix qui en serait
demand serait peut-tre justifi. Dans le cas contraire, la version libre restera libre
et pourra tenter de dvelopper les mmes services, voire mieux, ce qui sest dj vu.
Dans le pire des cas, rien ninterdit un autre groupe de dveloppeurs, libres ou lis
par une socit concurrente, de repartir du code existant et de crer un nouveau
projet driv de Maven, comme IBM la fait avec IBM HTTP Server. Cette situation
extrme a dj t rencontre dans le monde open-source et est qualifie de fork.
Il sagit cependant dune situation rare, une sorte de solution de la dernire chance
lorsque des conflits internes ne peuvent tre rgls lamiable. Cela reste une scurit non ngligeable que tout projet open-source offre : si le dveloppement
commence prendre une voie qui dplat une partie de lquipe, ils peuvent faire
le choix de mettre en pratique leurs propres ides, certes avec des effets nfastes sur
limage du projet, mais dmontrant ainsi la force du modle libre.
260
Partie III
Conclusion
Le comit nous remercie et sapprte dlibrer. Nous naurons sa conclusion quaprs
quelques jours (ce sont des gens trs occups) : feu vert.
Maven ne rpond pas toutes les exigences sans quelques efforts, et il ne sait pas non
plus faire le caf. Son utilisation ncessite un apprentissage, peut draper vers un grand
nimporte quoi si on ny fait pas attention et ncessite une prise de conscience de son
fonctionnement. Si vous lisez ces lignes, vous en tes probablement dj convaincu.
Maven est aussi un projet vivant, toujours ouvert de nouvelles ides, mme si elles
naboutissent pas en quelques semaines. Un outil utilis par des milliers de projets ne se
modifie pas la lgre. Lavenir de Maven est encore flou, toute prdiction de la disponibilit des prochaines volutions tant totalement alatoire, cependant il nest pas prs
de sarrter en si bon chemin. La communaut ne cesse de crotre, supporte par de
nouvelles socits dont il est le cur de mtier. Son succs en entreprise dmontre un
rel besoin dhomognit des outils de dveloppement, et de ce fait sa logique interne
fait mouche. Le modle open-source ne fait plus peur comme il y a quelques annes, et
ceux qui sont sa base ne sont plus des idalistes barbus en sandales + chaussettes mais
des professionnels pragmatiques.
L o les outils bass sur des scripts donnent de la flexibilit, Maven oppose une logique de matrise du processus et de ses tapes cls. Le nombre de lignes ncessaires pour
raliser telle tche na aucune importance, ce qui compte cest que loutil soit cohrent.
La concurrence commence suivre galement cette piste, apportant des ides nouvelles
qui pourront tout autant profiter Maven.
Nous sommes convaincus que Maven a encore de trs beaux jours devant lui. Maven 3
promet des volutions importantes qui feront sauter de nombreux verrous, comme en
tmoigne son intgration dans nos IDE. Quant larmada de plugins qui gravitent
autour, elle ne fait quaugmenter et prend une place croissante dans les dveloppements
de nouveaux outils. Jusquici, il ntait pas envisageable de proposer un outil sans une
tche Ant. Il devient dlicat de ne pas proposer galement un plugin Maven, sous peine
de crouler sous les rclamations rptes des utilisateurs.
16
Nos recommandations
Lactivit de noubliepaslalistedescourses ne cessant de crotre, nous augmentons rgulirement la taille des quipes charges des dveloppements, de la maintenance de notre
application et de ses drivs (voir le Chapitre 14). Avec une dizaine de nouvelles
recrues lors du dernier trimestre, il devient ncessaire dorganiser et dacclrer le
passage de connaissances. Cest Nicolas qui prend dsormais en charge laccueil des
nouveaux et organise rgulirement des formations pour que les quipes aient un niveau
minimal homogne. La partie des formations rserve Maven se veut minimaliste
mais efficace. Le but nest pas de faire de toute lquipe des experts capables de dvelopper des plugins, des nouveaux packagings ou encore de dboguer au besoin loutil.
Ce que nous souhaitons, cest que tous soient laise avec son fonctionnement et
quils suivent nos recommandations afin dviter les cueils que nous avons dj pu
rencontrer.
262
Partie III
Daprs nous, le meilleur moyen pour vous viter lavenir de mettre le pied sur une
peau de banane, cest de vous les montrer tout de suite. La plupart des formateurs
montrent de beaux exemples bien ficels qui collent parfaitement la technologie dont
ils vantent les mrites. Si cest ce que vous cherchez, jetez un il notre application
blanche, cest un chef-duvre du genre. Nous allons ici faire un tour des embches
que nous avons rencontres en utilisant Maven sur de nombreux projets.
Voici donc les 10 commandements de lutilisateur de Maven.
Commandement no 1 : Les conventions de Maven tu suivras.
Maven propose ses propres conventions mais ne les impose pas. Un projet que nous
avons fait migrer sous Maven utilisait comme rpertoire de sources le chemin src/
java et pour les tests test/java. Les POM ont donc t adapts pour coller cette
convention.
Nous avons perdu un temps prcieux reconfigurer de nombreux plugins, qui ont la
mauvaise ide dutiliser le chemin src/main/java en dur et pas la variable
${build.sourceDirectory}. Notre POM ne gagne pas en lisibilit, et cest cher pay
pour un petit caprice esthtique.
De la mme faon, ne considrez jamais les conventions comme acquises. Utiliser le
chemin /target/classes pour indiquer le rpertoire de compilation du projet, cest
potentiellement sexposer un dysfonctionnement. Nous en avons fait la mauvaise
exprience en configurant notre application pour utiliser Sonar (voir le Chapitre 12). La
convention pour ce chemin est porte par la variable ${project.build.outputDirectory}. Cest un peu plus long crire, mais cest une garantie dhomognit des mtadonnes du projet.
Le respect des conventions permet :
m
dviter de tomber dans des problmes ou des bogues qui font perdre un temps
prcieux.
Chapitre 16
Nos recommandations
263
Inutile de dire que la migration vers Maven a t laborieuse et pas du tout convaincante,
tant que nous navons pas pris la dcision de revoir fondamentalement la structure du
projet : des modules simples, cibls sur une technologie ou sur un domaine fonctionnel
prcis, et rpondant une logique de construction standard.
Il existe quelques projets qui refusent dutiliser Maven, sous prtexte quils ncessitent
dinnombrables lignes XML pour obtenir le rsultat attendu, lorsque cest possible.
Spring 2 en est un exemple, le framework tant toujours construit avec le bon vieux
Ant. Ce nest pourtant pas une fatalit, et cela a t dmontr dans Better Builds With
Maven (disponible librement en ligne), qui propose un POM permettant de construire
Spring sans acrobaties particulires.
Les dveloppeurs de Spring sont-ils tordus ? Non ! Par contre, ils ont fait des choix qui
vont contresens des prconisations de Maven. Par exemple, Spring est disponible la
fois comme un unique JAR et comme un ensemble de sous-bibliothques spcialises.
Ensuite, le cur de Spring 2 est compatible la fois Java 1.3 et Java 5, ce qui ncessite
une double compilation puis le regroupement du rsultat dans une unique archive JAR.
Bien que Spring ait rcolt un grand succs pour ses qualits techniques, les structures
de son code source et de son script de compilation le rendent inutilement complexe.
Aprs tout, si vous travaillez sur Java 5, vous pouvez trs bien dclarer une dpendance
vers spring:2.0.8:tiger1 la place de spring:2.0.8. Les dpendances transitives
feront le reste.
La morale de cette histoire, cest quil ne faut pas chercher plier Maven des besoins
complexes mais plutt essayer de comprendre comment traiter nos besoins selon la
philosophie de Maven. Autant Ant permet de faire peu prs tout et nimporte quoi,
autant Maven suppose quon adhre sa logique pour en tirer tout le bnfice.
Des projets comme Alfresco ou Liferay ne saccommodent pas facilement de Maven. Il
faut prendre le temps danalyser les besoins et dorganiser au mieux le projet pour tre
efficace.
1. Tiger est le nom du projet de dveloppement de Java 5, comme Dolphin est le nom de Java 6 et
Mustang celui de Java 7. De nombreuses librairies utilisent ce nom pour dsigner une version adapte
Java 5, ce qui sonne mieux que -j5.
264
Partie III
Voil un magnifique commentaire dont lutilit est sans appel ! Soit vous gnrez
lensemble des commentaires pour satisfaire Checkstyle, soit vous dfinissez une rgle
qui prconise la forme plutt que la pertinence du commentaire ou la clart du nom de
la mthode ! Sincrement, tout dveloppeur prfrera, mme sans commentaire Javadoc, une mthode nomme :
resilierContrat( long idContrat ) throws ImpayesEnCoursException
Choisir des rgles de dveloppement est une tche qui ncessite une culture et un historique de mise en uvre du langage. La tendance est aux noms de mthodes et de variables clairs, explicites, quitte faire long les crans 16:9 ont probablement aid cette
volution. Fini le code sur 80 colonnes ou lutilisation des tabulations !
Chapitre 16
Nos recommandations
265
Utiliser loutillage que Maven met notre disposition nest pas une fin en soi. Ce doit
tre laboutissement dune dmarche qui dfinit les rgles que nous voulons vrifier ou
les outils que nous voulons mettre en uvre. Introduits sur le projet un par un, ces outils
seront bien perus et leur plus-value reconnue. Imposs tout dun coup sans explication,
ils seront vcus comme une contrainte inutile et deviendront vite inutiliss, voire
contre-productifs.
De la mme faon, installer un serveur dintgration continue na de sens que pour des
quipes dj familiarises avec loutillage de tests automatiss et la pratique du dveloppement dirig par les tests, et sensibilises au surcot dun projet dont le code est
instable.
Inutile donc de barder notre POM de plugins en tout genre et de dclarations sans fin,
juste parce que le format du fichier le permet. Si personne ne les exploite ou ne sait
comment en tirer parti, ce sera du temps perdu, un travail contre-productif. Maven nest
quun moyen qui nous aide mettre en uvre les bonnes pratiques actuelles du dveloppement de logiciels. Il nest en aucun cas une solution magique. Il permet de mettre
en place diffrentes stratgies de tests (unitaires, dintgration) mais il ne le fera
jamais la place de nos quipes. Elles seules peuvent sassurer que les bonnes pratiques
sont suivies.
Commandement no 4 : De la sur-conception point tu ne feras.
Lapplication maxiMaousse2, elle aussi base sur Maven, comprend 58 modules ! Elle
suit une dcomposition en couches techniques ainsi quun redcoupage en modules
fonctionnels. Une modification fonctionnelle touche ainsi rarement plus dun ou deux
modules, rduisant thoriquement le travail de non-rgression.
En pratique, cette application est ingrable dans notre IDE en raison de lavalanche de
modules. Les volutions touchent rarement un seul module, et les interdpendances
sont nombreuses. La construction du projet sur un poste de dveloppement incluant les
tests unitaires et de qualit devient un vrai cauchemar, elle est surtout contre-productive
et lidentification du code un vrai casse-tte. Certains modules ne comptent que quelques classes ! Ici, on a visiblement confondu la notion de package et de module Maven.
La gestion multimodule de Maven est puissante, ce nest pas une raison pour lappliquer juste parce quelle existe. Nous ne crons un nouveau module que lorsquun
nouveau besoin apparat. Cela arrive dj suffisamment assez vite : par exemple, pour
rpondre une contrainte technique ou pour diffrencier deux modules qui travaillent
2. Si vous voulez voir quoi cela peut ressembler, un vrai projet ingrable et interminable construire
est Saka (http://sakaiproject.org/portal)
266
Partie III
sur des technologies diffrentes et dont nous voulons clairement scinder la gestion. Si la
dcomposition en modules fins peut avoir du sens pour une bibliothque utilitaire, elle
apporte rarement de la simplicit sur une application. Au mieux, on pourra dcouper
celle-ci en fonction de ses couches techniques afin de permettre des quipes de
comptences diffrentes dintervenir de manire plus isole. Cependant, les modules
resteront fortement dpendants ; aussi, pourquoi ne pas simplement utiliser des packages
ddis dans le mme projet ?
Le seul cas pratique o la dcomposition en modules peut apporter une certaine plusvalue concerne la gnration de code. Lorsquun projet est bas sur de nombreux services web, lanalyse des WSDL et la gnration de code prennent du temps, mme pour
constater que le code gnr est jour. Pour ne pas pnaliser les dveloppeurs sur leur
poste, isoler ce code dans un sous-module peut tre une bonne ide. Aprs tout, on ne
change pas de WSDL tous les matins !
Bref, les occasions de justifier le dcoupage dun module en plusieurs modules sont
nombreuses. Alors, nen faites pas plus que ncessaire. Vous testerez le racteur de
Maven bien assez tt.
Commandement no 5 : Tes outils et ton build jour tu maintiendras.
Mme si mettre en place loutillage de dveloppement nest pas une fin en soi, cest un
mal ncessaire, au cot non ngligeable, permettant doffrir lquipe un environnement aussi agrable que possible et optimis pour travailler. De trs nombreux outils
peuvent y figurer :
m
Maven, le programme en tant que tel mais aussi tous les plugins quil utilise ;
Il est important que ces outils soient matriss, mais il est encore plus important quils
soient mis jour et que leur intgration soit pousse son maximum. Celle-ci permet,
par exemple, via le numro du bogue plac dans le commentaire dun commit sur le
gestionnaire de sources, de faire le lien depuis le gestionnaire danomalies pour afficher
les lignes modifies par la correction. Ce genre dintgration fait gagner beaucoup de
Chapitre 16
Nos recommandations
267
temps pour la revue des corrections de bogues. Et les intgrations entre produits sont
nombreuses. Celles unifiant tous les services au sein de lIDE sont probablement celles
qui amlioreront le plus la productivit.
Les mises jour de chaque outil sont importantes. Prenez lexemple de Maven. Sur un
projet multimodule monstrueux provenant tout droit de lre jurassique (plus de
150 modules), Maven 2.0.10 mettait prs de huit minutes rien que pour sinitialiser et
gnrer lordre de construction des modules. Avec Maven 2.1.0 et suprieur, cela prend
moins dune minute. Mme si ce cas est extrme (mais bien rel), il est reprsentatif des
gains que lon peut obtenir en faisant leffort de maintenir jour ses outils.
Les projets durent longtemps et les outils voluent vite. Les maintenir jour permet
den obtenir le meilleur. Cela entrane un cot rcurrent mais qui est finalement vite
rentabilis par les gains de productivit de lquipe.
Commandement no 6 : Dans un projet, la mme version tous les modules
auront.
Sur un projet de messagerie, nous avons dvelopp une couche complte dabstraction
autour de lenvoi/rception de messages, indpendante du fonctionnel. Nous avons
voulu capitaliser dessus et la proposer dautres projets. Une fois ce code dplac dans
un module, il devenait exploitable sur une autre application qui profitait ainsi de nos
longues heures de mise au point.
La rutilisation est un rve de tout chef de projet. Seulement, lorsquune application
nous a demand dutiliser ce module, sest pos le problme de la gestion de sa version.
Notre demandeur ne voulait pas utiliser un SNAPSHOT ; sa livraison tant prvue sous
peu, il lui fallait un code stable. Notre code rpondait cette attente, mais tant li
notre application, il partageait son numro de version. Nous pouvions faire une
livraison isole de ce module, mais alors celui-ci rfrenait un parent encore en
SNAPSHOT !
Nous avons donc d figer notre POM parent dans une version 1, livrer le fameux
module mutualis en version 1.0.0 et continuer notre application en version 1.0.0SNAPSHOT. ce petit jeu, nous nous sommes rapidement retrouvs avec des versions
dans tous les sens dans les POM des diffrents modules et limpossibilit dutiliser le
processus de livraison dtaill au Chapitre 11.
La morale de cette histoire, cest que les modules dun projet devraient toujours partager la mme version, sans quoi la gestion manuelle des numros de version devient
infernale. Le plus simple pour satisfaire ce besoin est de ne dfinir cette version que
dans le POM parent du projet et dans les rfrences <parent>. Toutes les autres rfrences
se font via la variable ${project.version}. Ainsi, pas de risque de se tromper.
268
Partie III
Pour dclarer du code comme bibliothque commune, nous devons crer un nouveau
projet Maven indpendant : POM ddi, gestion de version ddie, gestionnaire de
code ddi, etc. Une fois notre code utilitaire prpar pour tre rutilisable ailleurs, sous
forme dun projet part entire, il ne peut plus tre considr comme un lment de
notre application, mme si celle-ci devient un contributeur privilgi de ce composant
commun.
Commandement no 7 : La gestion des versions tu centraliseras.
Dans un projet bas sur de nombreux modules, un travail vite pnible consiste
assurer la cohrence de versions des dpendances. Des plugins peuvent nous aider
dans cette tche, mais il existe une solution bien plus simple : le <dependencyManagement>. Cet lment, que nous allons ajouter dans le POM parent du projet, dclare
pour chaque dpendance la version de rfrence utiliser sur le projet. Dans les
modules, nous dclarons alors les dpendances sans prciser de version, liminant
ainsi le problme.
Le <pluginManagement> permet de faire la mme chose pour les plugins avec, en plus,
la possibilit de dfinir une configuration centralise, mais qui ne sera applique que sur
les modules qui utilisent le plugin.
INFO
Les plugins dclars pour le reporting ne profitent cependant pas de cette gestion centralise et doivent donc explicitement contenir un numro de version. Il sagit en quelque sorte
dun bogue de conception de Maven, mais le corriger supposerait de modifier le comportement gnral de Maven vis--vis de la gestion des versions. Lquipe de dveloppement
est trs rticente changer cette gestion qui peut avoir de lourds impacts sur les projets
existants.
Dclarer toutes ces dpendances, auquel cas les utilisateurs vont nous huer, se plaindre que Maven tlcharge des centaines de JAR inutiles et perdre des heures configurer des <exclusions>.
Chapitre 16
Nos recommandations
269
Dclarer ces dpendances <optional>, ce qui les rend juste indicatives. Nos utilisateurs ne vont pas nous huer tout de suite, mais plus tard quand, lors de lexcution,
ils constateront quune dpendance manque.
La philosophie de Maven nous encourage utiliser un module ddi pour chaque technologie ou outil que nous voulons supporter. Si cela veut dire avoir dix modules, ce
nest pas un problme. La gestion des dpendances et de la livraison tant automatise,
cela na aucun impact sur le temps pass par le dveloppeur sur son travail, la seule
chose qui compte au final. Par contre, nous gagnerons dans la finesse de nos mtadonnes
et dans la bonne dcomposition de notre code.
Commandement no 9 : Les SNAPSHOT tu utiliseras.
Sur un projet comptant plusieurs (dizaines de) modules et de trs nombreuses classes, il
peut tre pnalisant davoir tout le code accessible sous forme de projet dans lIDE.
Nous pouvons, par exemple, exploiter certains modules sous forme de SNAPSHOT,
comme celui contenant le code gnr de nos schmas XSD. Le conserver dans notre
IDE napporte rien et pnalise lintgration Maven qui va devoir sans cesse reconstruire
ce code, ou du moins sassurer quil est jour perte de temps que le dveloppeur
ressentira trs nettement :
m
Attendre cinq dix secondes, cest le temps ncessaire pour voir quil se passe quelque
chose et se reposer les poignets.
Attendre trente secondes que le projet compile, cela incite affubler son IDE de
noms doiseaux.
Attendre plus dune minute chaque construction, cest sexposer une monte
dnervement, souvent accompagne dune augmentation alarmante de la consommation de caf, qui ne suffit pourtant pas expliquer le premier phnomne. Peut-on
alors encore parler de productivit ?
En reposant sur les SNAPSHOT pour tous les modules dans lesquels nous ne faisons
aucune modification et qui correspondent du code voluant trs peu, nous allgeons
dautant le travail de lIDE. Notre serveur dintgration continue a le mrite de ne prendre ni pause ni caf. Il peut construire pour nous les SNAPSHOT de nos modules au fur
et mesure quune construction russie est atteinte.
Commandement no 10 : LIDE toujours tu privilgieras.
Cela fait trs expert de scruter la console et de taper une vitesse folle des commandes
incomprhensibles. Si vous envisagez un rle dans une srie amricaine, pourquoi pas ?
270
Partie III
mais si vous voulez travailler confortablement et former rapidement vos quipes, cherchez
plutt de laide du ct de votre environnement de dveloppement.
Trop souvent, nous perdons du temps sur les postes de dveloppement suite un
comportement bizarre de Maven. Le cas typique se traduit par un appel laide du
type : "Jai beau lancer des mvn clean install, project clean sous Eclipse, et
build all, je narrive pas dmarrer mon serveur Tomcat cause dune NoClassDefFoundError."
Le but du dveloppeur nest pas de passer son temps devant la Matrice3, surtout en
mode crypt (de toute faon, a fatigue vite les yeux). Il faut toujours privilgier la
productivit de lquipe, sans quoi les belles mthodes et les outils prconiss seront
vite oublis dans le feu de laction.
Nous avons vu au Chapitre 9 que cette intgration est dj trs correcte et progresse
mme rapidement sous Eclipse, qui est trop longtemps rest la trane. Apprenez bien
utiliser le support de Maven dans les IDE pour fournir lquipe un outil aussi transparent que possible. Les versions rcentes de m2eclipse proposent, par exemple, la variable m2eclipse qui permet de diffrencier un build classique dun build sous Eclipse. Un
bon moyen de rendre lIDE plus ractif est den profiter pour dsactiver les tapes non
indispensables de la construction du projet. Le Listing 16.1 montre lactivation dun
profil exclusivement en dehors de m2eclipse.
Listing 16.10 : Un profil pour viter les plugins trop consommateurs sous m2eclipse
<profile>
<id>not-m2e</id>
<activation>
<property>
<name>!m2e.version</name>
</property>
</activation>
<build>
<!-- plugins trop consommateurs lors des builds m2Eclipse -->
</build>
</profile>
Une autre option consiste exploiter lintgration avance sous Eclipse que permet le
mode incrmental de m2eclipse. Le Listing 16.2 montre une telle configuration pour
associer le plugin adapt la phase de recopie des fichiers de ressources. Lastuce
consiste, lors dun build m2eclipse, utiliser la version SNAPSHOT du plugin de
gestion des ressources (qui gre ce mode incrmental) et activer le configurateur
m2eclipse associ aux projets Java.
3. http://whatisthematrix.warnerbros.com/.
Chapitre 16
Nos recommandations
271
Listing 16.2 : Un profil pour activer le cycles de vie reconfigurable de m2eclise 0.9.9
<profile>
<id>m2e</id>
<activation>
<property>
<name>m2e.version</name>
</property>
</activation>
<build>
<plugins>
<plugin>
<groupId>org.maven.ide.eclipse</groupId>
<artifactId>lifecycle-mapping</artifactId>
<version>0.9.9</version>
<configuration>
<mappingId>customizable</mappingId>
<configurators>
<configurator id='org.maven.ide.eclipse.jdt.javaConfigurator'/>
</configurators>
<mojoExecutions>
<mojoExecution>org.apache.maven.plugins:maven-resources-plugin::
</mojoExecution>
</mojoExecutions>
</configuration>
</plugin>
</plugins>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>2.4</version>
</plugin>
</plugins>
</pluginManagement>
</build>
</profile>
Conclusion
En rsum, une rgle simple : nessayez pas daller contre Maven. Les conventions ont
t choisies pour reflter les bonnes pratiques et des rgles simples dorganisation. Sil
suit une logique qui va contre vos objectifs, cest que vous navez pas saisi son mode de
fonctionnement. Soyez critiques sur lorganisation de votre projet et de votre code.
Pourquoi Maven veut-il vous imposer tel mode de fonctionnement ? Vous arriverez sans
doute repenser votre structure pour quelque chose de plus simple, ordonn de manire
homogne, et qui se plie mieux au mode de pense de Maven. Au final, vos projets nen
seront que plus clairs et plus comprhensibles.
17
pilogue
Le dernier numro de Fortune vient de paratre. Dans son grand dossier central, il
prsente le projet Geegol Shopping List dont la russite est inversement proportionnelle leffort de dveloppement qui lui a t consacr. Larticle met en avant les qualits hors du commun de lquipe de dveloppement, de quoi faire baver tous les
directeurs informatique de la plante. Nous ne comptons plus les offres demploi, que
nous recevons par centaines chaque jour, toutes plus apptissantes les unes que les
autres.
Dans la vraie vie, les choses sont souvent moins roses. Les contes de fes et les histoires
fantastiques sont malheureusement rservs nos enfants. Pourtant, Maven peut tout de
mme nous aider conduire nos projets dans de bonnes conditions, mme ceux qui ne
sont pas de merveilleuses prouesses technologiques ou le sujet denjeux stratgiques.
274
Partie III
Rcapitulons
Bien que quelque peu embellie, lhistoire que nous venons de raconter est tire de situations relles, que nous avons tous vcues un moment ou un autre de nos carrires sur
divers projets. Dans chaque cas, la plupart de nos problmes taient lis un manque de
rigueur dans notre outillage ou alors un dfaut de matrise de ce dernier. Reposant sur
les qualits individuelles ou sur les connaissances de quelques personnes, un projet peut
vite tomber dans la tragdie loccasion dun cong (volontaire ou non). Maven est un
catalyseur pour structurer les dveloppements autour dun outil unique et dune
conception simple et homogne du projet.
Maven ne serait pas ce quil est sans les efforts de toute son quipe. La communaut
francophone y est largement reprsente avec Arnaud, Carlos, Emmanuel, Fabrice,
Herv, Lukas, Nicolas, Olivier, Raphal, Stphane et les deux Vincent. Tous, leur
niveau et des moments diffrents de leur parcours professionnel, ont mis un doigt
dans le monde open-source et en sont maintenant imprgns. Maven ne serait pas ce
quil est non plus sans Antonio, Franois, Guillaume, Sbastien, Jrme et les millions
dautres personnes qui chaque jour lutilisent, participent son support, dbattent de
son avenir, rapportent des anomalies et proposent des correctifs.
Maven est avant tout une trs large communaut de dveloppeurs, son cur ne servant
que de centre gravitationnel pour une galaxie entire de plugins. Certains sont structurs autour de la communaut via le projet Mojo, dautres vivent leur vie indpendamment. Tous contribuent faire de Maven un outil toujours plus riche.
Maven devient peu peu un outil stratgique en entreprise en apportant enfin une
homognit aux dveloppements. Un dveloppeur peut passer dun projet lautre,
voire dune entreprise lautre, sans remettre fondamentalement en question ses habitudes de travail. Lexprience aidant, les quipes de dveloppement apprendront
mieux utiliser les outils que Maven permet de greffer en quelques lignes de configuration
sur nimporte quel projet.
Sortez de lamateurisme
Certains parlent dindustrialisation du dveloppement, dautres simplement de renoncer
des pratiques qui tiennent du pur bricolage. Anecdote :
Nicolas, en tant quexpert Maven, est consult pour un projet en tierce maintenance. La procdure de compilation est la suivante :
"Lancer la commande ant jar. La construction choue, cest normal. Dmarrer Eclipse, attendre un certain temps puis quitter Eclipse. Lancer alors nouveau ant
jar."
Chapitre 17
pilogue
275
Cela semble compltement dlirant, mais cest crit noir sur blanc dans un document
officiel document qui est parfaitement conforme toutes les normes qualit
ISO 9001, AFAQ et compagnie ;).
Pour la petite histoire, le projet comprend une classe qui ne compile pas (elle fait rfrence des classes inconnues). Le compilateur excut par ant choue, alors
quEclipse produit tout de mme un fichier .class (incomplet). Le compilateur ne
cherchant pas recompiler une classe dj compile, le deuxime passage de ant
produit le rsultat dsir. Heureusement, cette classe est du code mort non utilis, mais
tout de mme !
Que retenir de ce cas extrme, mais qui vous rappelle peut-tre des situations qui ne
vous font pas honneur ? Simplement que le processus de construction du projet est un
lment majeur de lorganisation de votre travail. Utiliser un mcanisme instable,
dpendant de lenvironnement ou de manipulations manuelles, cest forcment sexposer des problmes un moment ou un autre, en gnral le vendredi soir juste avant
votre dpart en vacances. Maven ne rsoudra pas tous vos problmes, mais il vous fournit
un socle pour btir des solutions.
Le mot de la fin
Pour conclure, sachez que le Definitive Guide, ouvrage communautaire traduit dans de
nombreuses langues (la version franaise est en cours de ralisation lheure o nous
rdigeons ces lignes), est lui-mme rdig puis assembl via Maven. Pour produire les
500 pages du PDF que vous pouvez consulter en ligne1, il suffit de lancer la commande
universelle mvn install !
276
Partie III
Chapitre 17
pilogue
277
quand jai boss chez OTI (maintenant IBM Ottawa Lab) en 2001, dans lquipe
Eclipse Core o jai fait la premire version du plugin Ant. Jai ensuite fait beaucoup
"mumuse" en dveloppant tout plein de plugins (notamment crateur du plugin C# et
committer du plugin Checkstyle), mais pas forcment tous utiles ;-).
Utilisateur Maven depuis 2003, jai choisi Maven en 2004 pour crer la plateforme
dintgration dun grand groupe franais, et je suis finalement devenu committer en
2005. Puis vint Archiva en 2008 (committer et PMC). Depuis fin 2007, je suis directeur
technique de Qualixo, une petite socit spcialise en qualit logicielle, et je moccupe
notamment de dvelopper le business autour de Squale, une solution de qualimtrie
open-source, dans le cadre dun projet de recherche du ple de comptitivit
System@ticParis-Rgion. Donc malheureusement plus trop de temps pour les autres
projets :-(.
Ct personnel : passionn avant tout par la nature, jai pass les vingt premires
annes de ma vie Limoges, cest pour dire ;-). Bnvole WWF et ambassadeur de
lONG Plante Urgence : ma vraie passion, cest la protection de lenvironnement et la
solidarit internationale.
Herv Boutemy
Herv Boutemy, jai 37 ans, une femme et une fille, et je vis du ct de La
Dfense en rgion parisienne.
Je travaille depuis onze ans dans un grand groupe bancaire franais. Jai dbut par un
stage de R&D sur Java (avant la 1.0, des applets sur Netscape, optimises pour un
modem 14.4K) pour aujourdhui outiller de grands projets stratgiques, avec des
quipes rparties linternational, des accs mainframe, du couplage tlphonie informatique, des progiciels et autres subtilits de la ralit dun SI bancaire.
Si Maven 1 est rest au stade de test sur un projet open-source perso, jai eu suffisamment confiance en Maven 2 pour vouloir lintgrer en entreprise. Disposant dun
build Ant existant standardis et trs diffus, mon choix sest port sur les Maven Ant
Tasks. Elles taient plutt bogues, et cela a donc t loccasion de proposer des
patchs et de dcouvrir lenvers du dcor : beaucoup de code, beaucoup de gens intressants et pointus. Mais finalement beaucoup dendroits aussi o il reste des choses
faire. Je suis donc devenu committer en 2007 puis jai t intgr dans le PMC en
2008.
Aprs les Maven Ant Tasks, je me suis concentr sur la gestion de lencoding (pour ne
plus avoir mon prnom mutil par Maven), puis Modello. Un petit passage par Doxia
pour aider Vincent S. et Lukas : lexprience technique saccompagne de rencontres
humaines des plus varies.
278
Partie III
Ce livre original est un exemple de plus de toute la richesse de la communaut francophone autour de Maven.
Lukas Theussl
Salut tous,
2. http://www.opentravel.org/.
Chapitre 17
pilogue
279
quelque sorte "support" Maven dans le groupe. Jai commenc par Continuum (
lpoque o ctait un sous-projet de Maven) et un jour Emmanuel en a eu marre de
committer mes patchs et ma donc propos de rejoindre lquipe.
Maintenant, je me consacre aux plugins Maven (un peu au core pour la future 3.x).
Raphal Pironi
Jai 35 ans. Jai commenc utiliser Maven 1 en 2002 ou 2003 (je ne me
souviens plus), et pour Maven 2 depuis sa bta 1.
Voil. Je suis trs pnible pour la typographie bien que je fasse un bon tas de fautes
dorthographe.
Je dispose la maison du Lexique des rgles typographiques en usage lImprimerie
nationale ? 3e dition. Nicolas, je peux te le prter en cas de besoin ;).
Stphane Nicoll
J'ai 31 ans depuis peu, je vis dans une rgion magnifique l'est de la
Belgique.
280
Partie III
puis en tant que committer plus tard afin de rendre lutilisation de Maven plus solide et
dajouter des fonctionnalits manquantes, notamment au travers du dveloppement de
plugins (plus de dtails sur http://massol.net). Plus tard, jai particip aux longues
discussions de design sur Maven2
Jai (co-)crit trois livres dont deux sur Maven : JUnit in Action, aux ditions Manning,
Better Builds with Maven publi par lex-Mergere (maintenant Exist) et Maven :
A Developers Notebook, publi par OReilly.
Depuis 2007, jai dcroch du projet Maven (plus le temps) car je me suis donn corps
et me un nouveau projet open-source: XWiki3, un wiki dentreprise de deuxime
gnration (voire troisime ;)). Jy bosse la nuit (classique), mais aussi le jour (moins
classique) puisque je suis directeur technique de la socit XWiki SAS qui offre des
services, du support et du dveloppement spcifique au-dessus du projet open-source
XWiki.
Vincent Siveton
Jai pass le cap de lge du Christ au dbut de laventure de ce livre, soit 21
en hexadcimal ; daccord, cest trs geek, mais avouez que a rajeunit :).
3. http://xwiki.org.
Chapitre 17
pilogue
281
Si, depuis plusieurs annes, jutilise Maven sur la plupart de mes projets (y compris
mes projets hybrides, Flex et Java), cest cause de Vincent M., dArnaud et des autres
contributeurs que jai eu la chance de rencontrer ( JavaPolis, lOSSGTP, au ParisJUG, ou un comptoir) : leur enthousiasme et leur passion sont en effet contagieux
282
Partie III
PS : je suis galement lauteur dun blog technique autour des technologies Java et Flex
(http://www.droff.com).
Guillaume Laforge
Au dernier compte, jen arrivais 32 ans, dj.
Aprs douze ans dexprience en entreprise dans des domaines fonctionnels et techniques varis, je travaille actuellement sur un projet Java/J2E o Maven est largement mis
en uvre (merci Nico ;-)).
Quand jai install mon environnement, la consternation :
<mode panique: on>
Chapitre 17
pilogue
283
Par consquent, pour moi (et donc pour Nico), ce livre est une bndiction :-).
Post-scriptum
Nicolas De loof
Je ne remercierai jamais assez Arnaud davoir accept de maccompagner
dans cette aventure. crire un livre sur Maven sans en faire un pav inintressant ntait pas une mince affaire. Il a su protger ce rcit des appels si tentants du
ct obscur de la force.
Merci Pearson et en particulier Patricia de nous avoir donn notre chance pour ajouter
un titre la trop courte liste des ouvrages crits dans la langue de Molire.
Merci aussi tous les membres de la communaut Maven qui ont particip de prs ou
de loin la relecture de cet ouvrage et nous ont suggr de nombreuses amliorations.
Leur aide et leur tnacit ont t un excellent moteur.
Merci enfin mes ptits loups qui supportent que leur papa passe tant dheures devant
son cran.
Arnaud Hritier
Je remercie grandement Nicolas de mavoir propos ce challenge. Le
manque dune bonne documentation en franais sur Maven me titillait
depuis des annes. Il faut avouer que nous ne sommes pas vraiment reconnus pour notre
bon niveau en anglais, et cela se voit sur le terrain. Cependant, je naurais jamais eu le
courage de me lancer tout seul. Je le remercie encore plus pour la quantit de travail
quil a abattu (lessentiel en fait). Je suis trs fier de cet ouvrage qui est bien diffrent de
ce que lon peut voir dordinaire dans la lecture spcialise. Jespre que vous prendrez
autant de plaisir le lire que nous en avons eu lcrire.
284
Partie III
Merci notre diteur Pearson, et son quipe, Patricia, Amandine et tous ceux qui nous
ont accompagns dans cette premire exprience en tant quauteurs. Il faut avouer que,
pour des geeks comme nous, sortir la plume le traitement de texte (en plus celui de
Bilou !) et en faire louvrage que vous tenez dans les mains est un vritable exploit.
Merci nos relecteurs et toute la communaut Maven. Particulirement ses
membres francophones qui ont pu trouver le temps de nous pauler pour faire de cet
ouvrage une uvre de qualit.
Enfin, je dirai un grand grand grand merci mon exceptionnelle femme et mes trois
enfants qui supportent autant que possible le temps que je peux passer sur lopen-source
et ces derniers temps sur cet ouvrage.
18
Lexique
Ami lecteur, tu es arriv jusquici et notre rcit te laisse un got amer de "mais enfin, de
quoi parlent-ils ?". Il est vrai que linformatique possde un jargon riche, souvent
impntrable et anglophone Voici donc notre petit dictionnaire Maven Franais.
1. http://www.apache.org/.
2. http://www.apache.org/foundation/how-it-works.html#committers.
286
Partie III
ont dmontr en tant quutilisateurs avertis leur bonne connaissance technique ainsi que
leur capacit collaborer dans le respect de leurs pairs.
JIRA3
La socit Atlassian propose aux fondations qui hbergent des logiciels libres une
licence gratuite de son outil de gestion de tches et danomalies, JIRA. Cet outil est une
application web trs conviviale qui permet de suivre les actions en cours sur le projet et
dinteragir avec lquipe de dveloppement. Si vous rencontrez des comportements
anormaux, faites une recherche pralable sur le projet JIRA de Maven 4 ainsi que sur
ceux des plugins5. Vous pouvez dailleurs contribuer aux corrections par ce biais, en
attachant un mini-projet dmontrant le problme, et potentiellement un patch qui le
corrige. Atlassian offre dautres produits comme Confluence6, un Wiki trs rput.
Mailing-list
Le support de Maven (comme beaucoup dautres projets open-source) passe principalement par une liste de diffusion (Mailing-list) des utilisateurs (user@maven.apache.org
dans son cas). Une seconde liste dev@maven.apache.org permet de discuter des volutions de loutil et de ses plugins. La liste announce@maven.apache.org permet de
connaitre lensemble des livraisons. Il existe beaucoup dautres liste de diffusions en
fonction des sous projets de Maven7. Enfin, en cas de besoin urgent, vous pouvez
essayer de contacter une partie de lquipe de dveloppement sur irc 8.
Open-source (logiciel libre)
Logiciel dont le code source est accessible. Vous pouvez, si besoin est, y jeter un il
pour comprendre comment il marche. Les logiciels open-source sont aussi qualifis de
logiciels libres. Mais cela ne signifie pas pour autant que vous pouvez faire absolument
tout ce que vous voulez avec : il existe de nombreuses licences avec des contraintes trs
varies. La licence Apache (ASL v2) utilise par Maven est lune des plus souples
puisquelle vous donne le droit dutiliser, de modifier, de diffuser, voire mme de
vendre le logiciel comme bon vous semble tant que vous gardez un petit encart rappelant lorigine initiale du code. Un des meilleurs exemples de ce cas est le IBM HTTP
Server9, qui est une adaptation du serveur HTTP dApache.
3.
4.
5.
6.
7.
8.
9.
http://www.atlassian.com/software/jira/.
http://jira.codehaus.org/browse/MNG.
http://jira.codehaus.org/secure/BrowseProjects.jspa.
http://www.atlassian.com/software/confluence/.
http://maven.apache.org/mail-lists.html.
http://irc.codehaus.org/.
http://www-01.ibm.com/software/webservers/httpservers/.
Chapitre 18
Lexique
287
PMC10
La fondation Apache, pour la gestion des projets open-source quelle hberge, dfinit
un Project Management Commitee, constitu de committers plus expriments ou plus
actifs que les autres et qui peuvent ainsi dfinir de manire efficace les orientations du
projet. Le PMC a ainsi la responsabilit de voter la livraison dune nouvelle version, ou
dinviter de nouveaux membres comme committers.
10. http://www.apache.org/foundation/how-it-works.html#pmc-members.
288
Partie III
Build
Terme trs gnrique pour englober tout ce qui tourne autour de la construction du
projet, de son outillage et de lassurance qualit quon se donne le mal de lui associer.
Dpendances
Peu de bibliothques ou dapplications Java se contentent de la seule JRE. Les applications modernes reposent sur des dizaines dutilitaires ou de frameworks. On parle
globalement de dpendances, chaque dpendance ayant elle-mme ventuellement des
dpendances.
Cycle de vie
Le packaging dun projet Maven dfinit un cycle de vie, soit un ensemble de phases qui
seront enchanes. Les plugins Maven viennent se greffer une phase donne et sont
donc excuts selon cet ordre.
MAVEN_OPTS
La JVM qui excute Maven peut tre ajuste en dfinissant des options dans cette variable systme. Sur un projet un peu trop gnreux, vous pouvez par exemple rencontrer
des OutOfMemoryError: vous pouvez alors dfinir quelque chose comme "-Xmx512M XX:PermSize=128M
-XX:MaxPermSize=256M" dans la variable denvironnement
MAVEN_OPTS.
M2_HOME
Variable denvironnement pointant vers le rpertoire dinstallation de Maven. Elle
permet de configurer son environnement sans se baser sur des chemins en dur et donc
de changer plus facilement de version de Maven.
Mojo
Un plugin Maven est compos de classes Java, et chaque tche du plugin est ralis par
une classe Mojo, acronyme pour Maven Old Java Object (par allusion au terme POJO,
Plain Old Java Object). Un Mojo est donc le pendant ct code dune tche Maven
invoque par mvn plugin:tche. Les Mojos se basent sur une API propre Maven.
Voir sur ce sujet http://maven.apache.org/guides/introduction/introduction-toplugins.html.
Mojo est aussi le nom dun projet 11 offrant une collection de plugins surveills par
lquipe du projet Maven mais en dehors de la communaut Apache, ce qui permet
plus de flexibilit (sur le processus dentre des membres, ou sur les licences par
exemple).
11. http://mojo.codehaus.org/.
Chapitre 18
Lexique
289
Plugin
De manire gnrale, un plugin est un composant logiciel qui vient sajouter une
souche existante pour en enrichir les fonctionnalits. Dans le cas de Maven, comme
pour de nombreux systmes fonds sur ce mcanisme, le cur ne rend que les services principaux du logiciel (construction du POM, tlchargement des dpendances,
lancement des plugins) pour laisser les traitements aux plugins. Ces derniers participent la construction du projet en prenant en charge une tche particulire (produire
des rapports lors de la gnration documentaire, ou encore sexcuter de manire
isole).
POM12
Acronyme pour Project Object Model, en bon franais "modle du projet". Il sagit
du descripteur dun projet tel que Maven le construit en mmoire via un modle
objet interne. Ce modle est construit partir de fichiers XML, qui peuvent senrichir mutuellement via un mcanisme dhritage et de profils. Autrement dit, le
POM nest pas juste lquivalent mmoire du fichier pom.xml. Les versions venir
de Maven supporteront dailleurs des formats alternatifs - moins verbeux par
exemple.
Profile
Un profil permet de regrouper une partie de la configuration Maven, de lactiver / dsactiver la demande ou en fonction de conditions locales (version de JDK, systme
dexploitation, proprit systme, etc.). Lutilisation la plus courante est de dsactiver
certaines fonctions annexes du build qui seraient pnalisantes (trop lentes, ou bases sur
des pr-requis).
Release
Le processus qui permet de passer dun projet en cours de dveloppement un livrable
qualifi, trac et mis disposition des utilisateurs est qualifi de release, ce que nous
avons traduit par livraison. De nombreux cueils se dressent sur votre parcours pour
que toutes les tches impliques soient ralises sans oubli, maladresse ou autre loup.
Le Chapitre 10 vous explique en quoi Maven peut vous aider sur cette tche haute
valeur ajoute lorsquelle est correctement automatise.
Repository
Dpt (ou rfrentiel) dartefacts. Cela peut tre un simple partage rseau (URL en
file://) ou un serveur HTTP, mais pour une plus grande souplesse il est prfrable
dinstaller une vritable application ddie cette tche (Repository Manager) qui
12. http://maven.apache.org/pom.html.
290
Partie III
Chapitre 18
Lexique
291
Maven propose deux modes de gestion des Snapshots : soit la nouvelle version crase
simplement la prcdente, soit Maven dploie une version ddie pour chaque Snapshot en ajoutant une indication de date ( la milliseconde) plus un numro de diffusion,
incrment chaque nouveau Snapshot. Cette option consomme videment plus
despace disque sur le dpt, mais elle permet de figer lutilisation dun Snapshot particulier. Il faut prendre de grandes prcautions lors que lon utilise des artefacts en
version Snapshot car ces derniers ont tout loisir dtre modifis, ce qui peut donc entrainer
des rgressions ou des incompatibilits.
Staging
Afin dassurer la qualit du livrable dun projet, une option gnralement retenue dans
le processus de livraison est de construire ce dernier dans son tat final et de le soumettre des tests de validation. En cas danomalie, un retour arrire (rollback) est ralis et
un nouveau livrable pourra tre produit aprs correction. Pour diffrencier ce livrable
candidat du livrable public, on place le rsultat de la construction du projet dans un
espace ddi, appel stage dans le vocabulaire anglo-saxon. Cet espace est utilis par
lquipe de test qui matrise son environnement. Une fois le livrable valid, il suffit de
le transfrer de cet espace vers lespace public, sans aucune modification interne ? le
livrable public est donc bien celui qui a t test.
SureFire18
Maven supporte plusieurs outils de test unitaire : jUnit19 3 ou 4 et testNG20. Ce support
est orchestr par un outil ddi, SureFire ("infaillible"), sous-projet de Maven, qui fournit une vision homogne de ces trois outils, et permettra si besoin den intgrer un
nouveau dans le support de Maven. Le plugin Maven qui excute nos tests nest donc
pas un maven-junit-plugin, mais maven-surefire-plugin.
292
Partie III
Doxia22
Sous-projet de Maven, Doxia est le moteur de rendu documentaire de Maven. Il sert de
point darticulation entre diverses sources (rapports danalyse, format de documents) et
le rendu final (site web HTML, document PDF). Doxia offre une API permettant de
manipuler les diffrents formats dentre pour produire diffrents formats de sortie.
Mercury23
Le dveloppement de Maven 3 introduit une refonte de la gestion des artefacts, des
dpendances, de la rsolution des versions, ainsi que de laccs aux dpts (voir
Wagon). Mercury, sous-projet de Maven, est le nom de code de cette nouvelle API,
conue pour plus de clart et de flexibilit ? le code actuel de Maven 2 souffrant un peu
du poids des nombreuses annes de corrections diverses.
Modello24
Les divers fichiers XML manipuls par Maven sont dfinis partir dun modle (dcrit
dans des fichiers *.mdo), que loutil open-source Modello convertit en classes JavaBean, en schma XML et en analyseurs XML pour passer de lun lautre. Modello
peut potentiellement tre utilis dans un autre cadre mais reste trs li Maven.
Modello peut tre compar JAXB, lAPI actuelle qui normalise la passerelle entre les
mondes Java et XML.
Plexus25
Plexus est un conteneur IOC (Inversion Of Control) qui gre les composants de Maven.
Cest un projet indpendant de Maven et qui peut tre utilis dans un cadre trs diffrent. Cependant, son dveloppement a toujours t fortement li Maven (les dveloppeurs sont dailleurs en partie les mmes).
Wagon26
Lorsque Maven doit accder une ressource rseau, il passe par une couche ddie qui
gre divers protocoles (HTTP, HTTPS, SCP, WebDAV, etc.). Cette abstraction au
dessus des protocoles de communication est dfinie par lAPI Wagon, sous-projet de
Maven. Diverses implmentations permettent de supporter ces protocoles, voire den
ajouter de nouveaux. Vous pouvez par exemple utiliser le protocole de partage Windows
Samba via un module ddi27, qui nest pas intgr par dfaut Maven pour des questions
dincompatibilit de licence.
22. http://maven.apache.org/doxia/.
23. http://maven.apache.org/mercury/.
24. http://modello.codehaus.org/.
25. http://plexus.codehaus.org/.
26. http://maven.apache.org/wagon.
27. http://svn.codehaus.org/mojo/trunk/mojo/maven-extensions/wagon-cifs.
Chapitre 18
Lexique
293
28. http://maven.apache.org/doxia/references/apt-format.html.
29. http://maven.apache.org/doxia/references/fml-format.html.
30. http://www.eclipse.org/.
31. http://www.eclipse.org/equinox/.
32. http://nexus.sonatype.org/.
33. http://docs.codehaus.org/display/MAVEN/.
34. http://maven.apache.org/doxia/references/xdoc-format.html.
294
Partie III
Liens utiles
Et pour finir, quelques liens indispensables ajouter dans vos favoris :
m
http://www.sonatype.com/products/maven/documentation/book-defguide.
Le fameux definitive guide, en enrichissement permanent par les quipes de Sonatype.
http://www.packtpub.com/apache-maven-2-effective-implementations/book.
Encore un livre, crit lui aussi par des membres de lquipe Maven.
Sans oublier bien-sr deux sites absolument indispensables dans la vie dun dveloppeur
Java :
m
Index
Symboles
$HOME 101
A
notion de dpendance 23
solution de facilit 19
somme de contrle 96
Branche 165
Cargo 132
dploiement du livrable 167
APT 202
ClassWorlds 180
Archtype
create-from-project 229
dfinition 228
Checkstyle 193
Clover 196
Cobertura 196
Archiva 105
Compilateur
version cible 33
Artifactory 105
B
Bibliothque
conflits 25
dclinaisons 21
dpendances transitives 24
dploiement 172
dsillusions 27
doublons 28
erreurs de tlchargement 91
gestion centralise 111
installation manuelle 94
les difficults 18
mise niveau 18
moteur de recherche 92
Convention
adopter 15
code gnr 49
hirarchie de modules 111
nos recommandations 262
principe 11
Cycle de vie, prsentation 45
D
Dpendances, analyse 30
dependencyManagement 111, 224
Dpt
complexit 99
miroir 101, 103
outil ddi 100
296
Apache Maven
Dpt (suite)
prsentation 21
priv 96
serveur HTTP 96
Doxia 200
J
E
Eclipse
dclinaisons 142
difficults 148
support Maven 143
sysdeo-tomcat 136
Web Tools Platform 135
Emma 196
JEE
6e dition 138
archive d'entreprise 126
descripteurs de dploiement 120
Eclipse WTP 135
EJB 123
l'enfer des classloaders 121
prsentation 119
productivit 134
tester 128
exclusions 29
L
F
FindBugs 194
G
Licence
GPL 94
propritaire 94
SUN BCL 98
M
m2eclipse 143
interrogations 149
profil ddi 270
H
Hritage, prsentation 108
Hudson 116, 206
prsentation 69
I
Idea 149
Maven, installation 8
Intgration continue
au-dl 166
choisir 70
multi-module 115
multi-niveau 85
Index
N
NetBeans 153
Nexus 104
O
optional 28, 127
nos recommandations 269
OSGi 221
compatibilit 253
conflit 237
similitudes 181
Tycho 257
P
packaging
ejb 123
maven-plugin 175
pom 109
produire du Flash 50
valeur par dfaut 46
war 121
Plexus 253
composants 179
conteneur 179
utils 180
Plugin
analyse de code 264
antrun 172
archetype 226, 229
assembly 217, 220
buildnumber 211
cargo 132, 236
checkstyle 147, 198
ClassLoader 180
compiler 35
configuration 35
cxf 49
dbunit 80
dependency 30
documentation 36
ear 126
eclipse 142
diteur 145
ejb 124
enforcer 113
expression 177
fitness 83
gestion centralise 113
gpg 215
groovy 40
gwt 43
invocation 45
invoker 187
jetty 135
jmeter 85
o les trouver ? 53, 237
paramtres 177
pdf 201
proprits 36
release 160, 161, 166
selenium 130
site 199
sonar 205
sql 79
surefire 130
tches (goals) 41
tester 185
testing-harness 186
version 40
war 135
pluginManagement 113
reports 199
PMD 195
POM
dfinition 12
diteur 150, 154
dition 145
format XML 236
hritage 108, 115
indication SCM 160
modules 114
mutualisation 109
parent 110
POM d'entreprise 224
publication 93
297
298
Apache Maven
Profil
dsactiver 78
en fonction de l'environnement 76
m2eclipse 270
pour la livraison 158
prsentation 75
R
release candidate 164
rollback 163, 164
S
scope
prsentation 27
provided 27
system 95
test 27, 61, 144
avec un 57
contrle systmatique 65
couverture 196
dbrayer 65
dpendances de test 58
dveloppement pilot par les tests 62
cosystme 87
fonctionnel 82
framework 60
GwtTestCase 73
intrt et cot 56
introduction jUnit 58
JEE 128
module ddi aux tests d'intgration 131
performance 84
tester les EJB 137
unitaire ou non ? 74
Web 129
U
Selenium 128
settings.xml 103
SNAPSHOT 160, 215
nos recommandations 269
Sonar 204
Sonatype 257
open-source 257
stage 164
T
Test
accs aux fichiers 60
automatisation 56
du dploiement 132
V
Version
centralisation 268
dfinition 13
gestion centralise 111
homongnit 267
identification prcise 20
livraison 157
MANIFEST 19
W
Wiki 159
Rfrence
Apache
Maven, loutil open-source de gestion et dautomatisation de dveloppement Java, a le vent en
poupe. Les raisons : il systmatise, rationalise et
simplifie le dveloppement collaboratif de projets
Java, faisant gagner aux entreprises comme aux
dveloppeurs du temps et de largent !
Les auteurs, membres de lquipe de dveloppement Maven, aids par toute la communaut francophone, ont imagin de prsenter Maven 2 sous
un angle original et didactique, travers un projet
fictif, inspir de leurs expriences sur le terrain,
dont ils dtaillent toutes les phases successives. Ce
projet volue au fil des besoins et de la contribution
de dveloppeurs aux profils diffrents, vous familiarisant avec les concepts fondamentaux de Maven
et leur mise en uvre pratique, mais aussi avec les
fonctionnalits plus avances. Vous profitez galement des recommandations et bonnes pratiques
pour optimiser votre utilisation de Maven.
Vous dcouvrez ainsi de manire ludique et grce
des exemples concrets le potentiel de Maven,
et tous les avantages quil peut apporter vos
propres projets.
Programmation
Introduction
Au-del de java.lang
Un peu plus que compiler
Mettre en place des tests unitaires
Mettre en place des tests dintgration
Gestion avance des dpendances
Quand le projet devient trop lourd
Maven et JEE
Maven et les IDE
Le jour J : la livraison
Utiliser un outil non support
Lassurance qualit
Respecter un format de distribution
Un nouveau projet dmarre
Avons-nous fait le bon choix
Nos recommandations
pilogue
Lexique
ISBN : 978-2-7440-4098-6