Vous êtes sur la page 1sur 320

Apache

Nicolas De loof et Arnaud Hritier Prface de Jason Van Zyl

Rfrence
Rseaux et tlcom Programmation Gnie logiciel Scurit Systme dexploitation

http://www.free-livres.com/

Apache Maven
Nicolas De loof et Arnaud Hritier

Avec la contribution des membres francophones de la communaut Maven, en particulier Stphane Nicoll, Vincent Siveston, Raphal Pironi, Herv Boutemy, Jrme Van Der Linden, Antonio Goncalves et Franois Le Droff

Pearson Education France a apport le plus grand soin la ralisation de ce livre an de vous fournir une information complte et able. 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.

Publi par Pearson Education France 47 bis, rue des Vinaigriers 75010 PARIS Tl. : 01 72 74 90 00 www.pearson.fr Mise en pages : TyPAO ISBN : 978-2-7440-4098-6 Copyright 2009 Pearson Education France Tous droits rservs

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.

Table des matires


Table des listings ................................................................................................................ Prface ................................................................................................................................ XI XIII

Avant-propos ...................................................................................................................... XVII Contenu ....................................................................................................................... XIX

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 conguration ..................................................................... Dcrire plutt que programmer ............................................................................. POM ...................................................................................................................... Pourquoi adopter ces conventions ? ...................................................................... La force de Maven ...................................................................................................... 2 Au-del de java.lang .................................................................................................. Des JAR sous CVS ...................................................................................................... Quand le rpertoire lib explose ........................................................................... Identication univoque ......................................................................................... Dpt de bibliothques ......................................................................................... Avis aux amateurs de casse-tte ................................................................................. Lami de mon ami ............................................................................................. Testons un peu ............................................................................................................ Les "scopes" .......................................................................................................... 3 3 4 6 7 8 10 11 12 12 15 16 17 17 17 20 21 22 23 26 27

IV

Apache Maven

Une arme double tranchant ...................................................................................... Lanalyse des dpendances ................................................................................... Conclusion .................................................................................................................. 3 Un peu plus que compiler ............................................................................................ tes-vous prt pour Java 7 ? ....................................................................................... Plugins ........................................................................................................................ Proprits .................................................................................................................... Quand Java ne suft plus ............................................................................................ O placer les sources ............................................................................................ Ajouter un plugin .................................................................................................. Plugin et tches ..................................................................................................... Compiler en JavaScript ........................................................................................... Invoquer un plugin ................................................................................................ Cycle de vie .......................................................................................................... Gnrer du code .......................................................................................................... Produire autre chose quun JAR .................................................................................. Des plugins pour tout ? ............................................................................................... Conclusion .................................................................................................................. 4 Mettre en place des tests unitaires .............................................................................. Tester ? Pour quoi faire ? ............................................................................................ Automatisons ! ...................................................................................................... Utiliser un framework de test ................................................................................ Les tests sous Maven .................................................................................................. Le scope "test" ...................................................................................................... Le dveloppement pilot par les tests ................................................................... Pas de JAR sans tests russis ................................................................................. Rutiliser notre outillage de test ........................................................................... Lintgration continue ................................................................................................. Continuum ............................................................................................................ Hudson .................................................................................................................. Lequel choisir ? ..................................................................................................... Conclusion .................................................................................................................. 5 Mettre en place des tests dintgration....................................................................... Des tests unitaires de moins en moins unitaires ..................................................... Quest-ce quun test "unitaire" .............................................................................. Les prols ................................................................................................................... Sadapter lenvironnement ................................................................................. Dsactiver la demande ....................................................................................... Tester laccs une base de donnes ..........................................................................

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

Utiliser des tests fonctionnels ..................................................................................... Tester la charge et les performances ........................................................................... Intgration continue .............................................................................................. Conclusion ..................................................................................................................

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 chier 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 .................................................................................................................. 7 Quand le projet devient trop lourd ............................................................................. Un projet un artefact ................................................................................................ Hritage ................................................................................................................. Packaging dun POM parent ................................................................................. Parent "naturel" ..................................................................................................... Mutualiser ................................................................................................................... Gestion des dpendances ...................................................................................... Gestion des plugins ............................................................................................... Diviser pour rgner ..................................................................................................... Hritage "naturel" ................................................................................................. Et lintgration continue ? ..................................................................................... Un gros projet vs plein de modules ....................................................................... Les modules au service de larchitecture .............................................................. 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

8 Maven et JEE ................................................................................................................ Java Entreprise Edition ............................................................................................... Construire une archive web WAR ......................................................................... Construire un EJB ................................................................................................. Construire une archive dentreprise EAR ............................................................. Tester .......................................................................................................................... Selenium ............................................................................................................... Cargo ..................................................................................................................... Soyons pragmatiques, soyons productifs .................................................................... Une application web "sur place" ........................................................................... Une application web sans assemblage .................................................................. Ne plus sortir de lIDE .......................................................................................... Tester les EJB ........................................................................................................ JEE6 .......................................................................................................................... Conclusion .................................................................................................................. 9 Maven et les IDE........................................................................................................... Un plugin Maven pour Eclipse ............................................................................. Maven vu depuis lIDE ......................................................................................... Eclipse ........................................................................................................................ Installation ............................................................................................................ Import dun projet Maven ..................................................................................... Prise en main ......................................................................................................... Gestion du POM ................................................................................................... Intgration des plugins Maven .............................................................................. Et la cerise ......................................................................................................... Interrogations ........................................................................................................ Intellij Idea .................................................................................................................. Import dun projet Maven ..................................................................................... Gestion du POM ................................................................................................... Intgration des plugins Maven .............................................................................. Bonus .................................................................................................................... NetBeans ..................................................................................................................... Prise en main ......................................................................................................... Import dun projet Maven ..................................................................................... Gestion du POM ................................................................................................... Intgration des plugins Maven .............................................................................. Bonus .................................................................................................................... Dlibration du jury .................................................................................................... Conclusion ..................................................................................................................

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

10 Le jour J : la livraison ................................................................................................ Stratgie de livraison .................................................................................................. Premire livraison ................................................................................................. Deuxime livraison ............................................................................................... Troisime livraison ............................................................................................... Documentation ...................................................................................................... Le plugin release ...................................................................................................... tape 1 : prparation ............................................................................................. tape 2 : livraison ................................................................................................. Et si a foire ? ....................................................................................................... Notre prochaine version ........................................................................................ Tester des candidats .................................................................................................... Urgence ! .................................................................................................................... Au-del de lintgration continue ............................................................................... Conclusion ..................................................................................................................

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 .................................................................................................................. 12 Lassurance qualit..................................................................................................... Audit de code .............................................................................................................. Analyse statique .................................................................................................... Analyse dynamique ............................................................................................... 171 171 172 174 174 174 176 177 178 180 183 185 186 187 189 191 191 192 195

VIII

Apache Maven

Les rapports Maven .................................................................................................... Autre chose que du HTML ................................................................................... Exploiter notre gestion documentaire ......................................................................... 68 %, qui dit mieux ? ............................................................................................ Lentropie augmente ............................................................................................. Matrise de S ......................................................................................................... Sonar ..................................................................................................................... Conclusion .................................................................................................................. 13 Respecter un format de distribution......................................................................... Do vient ce JAR ? ..................................................................................................... Numro de construction ........................................................................................ Numro de rvision ............................................................................................... Utiliser le MANIFEST .......................................................................................... La conance rgne .................................................................................................. LEAR ne suft pas .................................................................................................... Assemblage du livrable ......................................................................................... Lintgration continue produit notre livrable ........................................................ Luf ou la poule ? ............................................................................................... OSGi ? ........................................................................................................................ Conclusion .................................................................................................................. 14 Un nouveau projet dmarre....................................................................................... Mutualiser ................................................................................................................... Qui paye ? ............................................................................................................. Partager un POM parent ....................................................................................... Copier-coller ......................................................................................................... Copier et mutualiser ! ................................................................................................. Un plugin qui cre des projets .............................................................................. Un archtype ? ...................................................................................................... Construire ses propres archtypes ......................................................................... Grer un projet de rfrence ....................................................................................... Donner le meilleur de nous-mmes ...................................................................... Dmarrer sur les bons rails ................................................................................... Un support pour exprimenter .............................................................................. Un support de dmonstration ................................................................................ Conclusion .................................................................................................................. 15 Avons-nous fait le bon choix ? ................................................................................... Les limites .................................................................................................................. Points faibles ......................................................................................................... Les plugins ............................................................................................................

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 .................................................................................................................. 16 Nos recommandations ................................................................................................ Les bonnes bases ........................................................................................................ Commandement n 1 : Les conventions de Maven tu suivras. ............................. Commandement n 2 : Simplicit tu choisiras. .................................................... Commandement n 3 : Au fur et mesure de tes besoins, les outils ncessaires tu mettras en place. ............................................................................................... Commandement n 4 : De la sur-conception point tu ne feras. ........................... Commandement n 5 : Tes outils et ton build jour tu maintiendras. .................. Commandement n 6 : Dans un projet, la mme version tous les modules auront. ........................................................................................ Commandement n 7 : La gestion des versions tu centraliseras. .......................... Commandement n 8 : Comme la peste les dpendances optionnelles tu viteras. ............................................................................................................. Commandement n 9 : Les SNAPSHOT tu utiliseras. .......................................... Commandement n 10 : LIDE toujours tu privilgieras. ..................................... 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 n ........................................................................................................... Qui est qui ? ................................................................................................................ Les membres francophones de lquipe Maven .................................................... Les membres de la communaut Java ................................................................... Post-scriptum ........................................................................................................ 18 Lexique ........................................................................................................................ Le petit monde open-source ....................................................................................... Les concepts Maven ................................................................................................... Ceux qui font tourner Maven ...................................................................................... Et tout ce qui tourne autour .................................................................................... Liens utiles .................................................................................................................. Index ...................................................................................................................................

273 274 274 275 275 275 281 283 285 285 287 291 293 294 295

Table des listings


Listing 1.1 : Les chiers de compilation utiliss respectivement par Nicolas et par Arnaud Listing 1.2 : pom.xml ......................................................................................................... Listing 1.3 : Premire excution de Maven ........................................................................ Listing 1.4 : Seconde excution de Maven sans tlchargement cette fois .................... Listing 1.5 : Len-tte du chier POM ............................................................................... Listing 1.6 : Le bloc build du chier POM ...................................................................... Listing 1.7 : Le bloc dependencies du chier POM ....................................................... Listing 2.1 : Excution de mvn dependency:tree ........................................................ Listing 3.1 : Production dun binaire SWF ........................................................................ Listing 4.1 : Une mthode main de test ............................................................................. Listing 4.2 : Utilisation dune bibliothque utilitaire dans le test ...................................... Listing 4.3 : Utilisation de jUnit ......................................................................................... Listing 4.4 : Accs aux chiers de test en tant que ressources ........................................... Listing 4.5 : Construction dun test-jar en mme temps que larchive java du projet .. Listing 4.6 : Utilisation dune dpendance exploitant la notion de classier .................... Listing 5.1 : Un prol ddi aux tests GWT ...................................................................... Listing 5.2 : Activation dun prol en fonction du systme dexploitation ........................ Listing 5.3 : Prol contrlant le respect des rgles de codage ........................................... Listing 5.4 : Prparation dune base de donnes de test "propre" avec le plugin SQL ...... Listing 5.5 : Conguration du plugin Fitnesse ................................................................... Listing 6.1 : Erreur de rsolution des dpendances ............................................................ Listing 7.1 : pom parent du projet ....................................................................................... Listing 7.2 : Utilisation du plugin Enforcer ....................................................................... Listing 8.1 : Descripteur de dploiement de notre EJB ...................................................... Listing 8.2 : Descripteur de dploiement de notre application web ................................... Listing 8.3 : Test Selenium en syntaxe Java ....................................................................... 5 7 8 9 13 14 14 30 51 57 58 59 61 66 67 75 77 78 80 83 91 109 113 124 125 129

XII

Apache Maven

Listing 8.4 : Conguration du plugin Selenium ................................................................. Listing 8.5 : Conguration du plugin Surere pour excuter nos tests Selenium .............. Listing 8.6 : Conguration du plugin Cargo ...................................................................... Listing 8.7 : Lancement dOpenEJB embarqu dans un test ............................................. Listing 11.1 : Utilisation du plugin AntRun ...................................................................... Listing 11.2 : En-tte POM du plugin documentaire ......................................................... Listing 11.3 : Notre classe Mojo de base ........................................................................... Listing 11.4 : Construction dun royaume ClassWorlds ddi lexcution de GEACheck Listing 11.5 : Invocation par rexion de loutil GEACheck ............................................. Listing 11.6 : Le mojo GEACheck en version Groovy ...................................................... Listing 11.7 : Test unitaire pour un plugin, bas sur le plugin-testing-harness ...... Listing 11.8 : Pseudo-POM charg lors du test .................................................................. Listing 11.9 : Conguration du plugin invoker ............................................................... Listing 11.10 : Script Groovy de contrle de lexcution .................................................. Listing 12.1 : Le descripteur de notre site .......................................................................... Listing 12.2 : Conguration du plugin Sonar ..................................................................... Listing 13.1 : Exploiter le numro de construction de Hudson .......................................... Listing 13.2 : Obtenir le numro de rvision SVN ............................................................. Listing 13.3 : Ajout de mtadonnes dans le MANIFEST ................................................. Listing 13.4 : Mise en place dune signature GPG ............................................................. Listing 13.5 : Le chier assembly ...................................................................................... Listing 13.6 : Invocation du assembly:single au cours de la construction du projet ... Listing 13.7 : Un POM ddi lassembly ........................................................................ Listing 14.1 : Un POM dentreprise pour Geegol .............................................................. Listing 14.2 : Gnration dun nouveau projet partir dun archtype ............................. Listing 14.3 : Structure de chiers gnre ........................................................................ Listing 15.1 : Un script simple de build Gradle ................................................................. Listing 15.2 : Un POM Maven 3 bas sur les attributs XML ............................................. Listing 16.1 : Un prol pour viter les plugins trop consommateurs sous m2eclipse ....... Listing 16.2 : Un prol pour activer le cycles de vie recongurable de m2eclise 0.9.9 ....

130 131 132 137 173 175 176 182 183 184 186 187 188 188 199 205 210 211 213 215 217 219 220 225 226 227 243 254 270 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 dnir 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 nal 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 signicatif 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 nale 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 bncient 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 dnir 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 difcile 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 ctif, 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

XVIII Apache Maven

romance vous montrer les difcults 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 ction se cachent des cas bien rels, que je nai fait quamplier, et beaucoup auront des points communs avec vos propres difcults. 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. Enn, 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 difcile 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 Denitive 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

ctif, 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 an quil ne soit plus jamais complexe vos yeux. Arnaud Hritier

Contenu
Cet ouvrage se compose de quatre parties :
m

La premire, du Chapitre 1 au Chapitre 5, aborde les concepts fondamentaux de Maven et leur mise en uvre pratique. Nous avons choisi de mettre en scne de manire trs explicite et souvent exagre les problmes que Maven tente de prendre en charge, an que cette premire partie soit aussi didactique que possible. 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. La troisime regroupe les Chapitres 11 15 et couvre des facettes plus spcialises et moins mises en avant de Maven, mais que nous considrons comme tout aussi essentielles. Vous verrez alors que Maven ne se rsume pas comme on le lit souvent "un outil de compilation". 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 rement, 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.

Premiers pas avec Maven

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 chiers 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 magnique relique des annes Java 1.1 et tente de le compiler. Seulement, Arnaud est un utilisateur Mac. Le chier 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 chier de compilation adapt son environnement an de pouvoir tester ce chef-duvre de linformatique. Deux jours plus tard, protant 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 chier contenant la liste des courses. Il lenvoie donc Arnaud, qui une nouvelle fois doit crire son propre chier de compilation. Le "projet" tant trivial, la traduction du build.bat en build.sh est rapide. Voici pour comparaison les deux chiers utiliss respectivement par Nicolas et Arnaud. Les diffrences sont minimes mais ncessitent une reprise manuelle chaque modication, 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 mkdir build javac -d build src\*.java jar cf noubliepaslalistedescourses.jar build\*.class #!/bin/bash export JAVA_HOME=/opt/jdk1.3 export PATH=$JAVA_HOME/bin export CLASSPATH=lib/mail.jar:lib/ activation.jar mkdir build javac -d build src/*.java jar cf noubliepaslalistedescourses.jar build/*.class

De nombreux projets industriels ou communautaires sont confronts ce mme problme et sont obligs de maintenir deux versions (ou plus) du script de construction du logiciel, soit parce que lquipe nest pas homogne, soit parce que lenvironnement de test ou de production nest pas quivalent celui de dveloppement. Mme sur des systmes dexploitation identiques, les outils peuvent tre installs des emplacements diffrents, ce qui oblige prvoir dans le script un ensemble de proprits que chacun devra renseigner en fonction de sa conguration. Sur Unix, ce problme a t trait depuis longtemps par loutil make. Cependant, celuici nest pas facilement exploitable sur les machines Windows, omniprsentes comme postes de dveloppement. Arnaud raconte ses dboires son collgue Olivier. Ce dernier, utilisateur du systme Solaris, sest souvent trouv face ce problme ; il lui propose dutiliser un chier de commande universel, bas sur loutil Apache Ant.

Premiers pas avec Maven

Partie I

Les fourmis la rescousse


Quest-ce que cest que ce "Ant" ? Faisons un dtour par Wikipdia pour nous en faire une ide :
INFO Ant est un projet open-source de la fondation Apache, crit en Java, qui vise le dveloppement dun logiciel dautomatisation des oprations rptitives tout au long du cycle de dveloppement logiciel, linstar des logiciels Make1. Le nom est un acronyme pour Another Neat Tool (un autre chouette outil). Ant est principalement utilis pour automatiser la construction de projets en langage Java, mais il peut ltre pour tout autre type dautomatisation dans nimporte quel langage. Parmi les tches les plus courantes, citons la compilation, la gnration de pages HTML de document (Javadoc), la gnration de rapports, lexcution doutils annexes (checkstyle, ndbugs, etc.), larchivage sous forme distribuable (JAR, etc.).

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 chier dOlivier suppose que les chiers 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 chier dOlivier est ant package alors que celle de Fabrice est ant jar. La fusion de ces deux chiers, 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

Ant a donc cr un nouveau mtier dans le microcosme informatique : expert en script Ant ! Certains projets semblent jouer pour le concours du script le plus inutilement tordu, mixant des paramtres nen plus nir (que personne na dailleurs jamais eu besoin de modier) et prenant en charge des cas de gure qui tiennent de lexpression artistique, le tout en important dautres chiers de script pour viter lignoble copiercoller. Sils sont fonctionnels, de tels scripts sont un enfer maintenir et traduisent une organisation suspecte du projet, qui pourrait bien avoir laiss passer un lment de complexit inutile. Pris au jeu, nos quatre amis qui ont trouv un boulot en or pour avoir autant de temps libre ne savouent pas vaincus et veulent poursuivre ensemble le dveloppement de ce projet. Des complications commencent merger. Notre petite quipe provenant dhorizons diffrents, chacun a ses habitudes "maison" et ses bonnes pratiques et voudrait les voir appliques.

Et Maven dans tout a ?


Au hasard dun de ces appels au secours, Jason les prend contre-pied et leur rpond : "Et pourquoi ne pas utiliser plutt Apache Maven ?" Surpris, et quelque peu incrdules devant cette proposition, ils mettent Jason au d de compiler ce fameux logiciel avec son outil miracle, l o nos deux scripts Ant, pourtant irrprochables, pris sparment refusent obstinment la fusion. Et dix minutes plus tard, Jason envoie un chier de quelques lignes, dune simplicit surprenante, et les instructions de base pour installer Maven. leur grande surprise, chacun arrive compiler le projet sur son environnement, quelle que soit sa singularit. Voici le chier envoy par Jason :
Listing 1.2 : pom.xml
<project> <modelVersion>4.0.0</modelVersion> <groupId>fr.noubliepaslalistedescourses</groupId> <artifactId>noubliepaslalistedescourses</artifactId> <version>0.0.1-SNAPSHOT</version> <build> <sourceDirectory>src</sourceDirectory> </build> <dependencies> <dependency> <groupId>javax.mail</groupId> <artifactId>mail</artifactId> <version>1.4</version> </dependency>

Premiers pas avec Maven

Partie I

<dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>1.4</version> </dependency> </dependencies> </project>

Compar aux chiers Ant tests jusquici, ce chier "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 ?

Que fait Maven ?


pluchons point par point les consignes de Jason et voyons. Linstallation de Maven proprement parler se rsume dsarchiver un chier ZIP et dnir la variable PATH pour y ajouter le chemin vers le rpertoire apache-maven/bin. Il faut aussi sassurer davoir la variable denvironnement JAVA_HOME qui indique lemplacement du JDK (Java Development Kit), ce qui est gnralement le cas sur le poste de travail des bons dveloppeurs. La construction du projet seffectue ensuite via la commande mvn package depuis la ligne de commande. Rien de bien rvolutionnaire donc par rapport au script Ant que nous avions envisag. Jason nous a indiqu que Maven ncessitait une connexion Internet. Linstallation nest donc pas complte, et Maven va rechercher sur le rseau les lments manquants. Effectivement, la premire excution de Maven se traduit dans la console par une srie de messages de tlchargements divers :
Listing 1.3 : Premire excution de Maven
D:\noubliepaslalistedescourses>mvn package [INFO] Scanning for projects... [INFO] -----------------------------------------------------------------------[INFO] Building Unnamed - fr. noubliepaslalistedescourses:noubliepaslalistedescourses:jar:0.0.1-SNAPSHOT [INFO] task-segment: [package] [INFO] -----------------------------------------------------------------------Downloading: http://repo1.maven.org/maven2/org/apache/maven/plugins/maven-resources-

plugin/2.2/maven-resources-plugin-2.2.pom
1K downloaded Downloading: http://repo1.maven.org/maven2/org/apache/maven/plugins/maven-plugins/1/

maven-plugins-1.pom
3K downloaded

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 bnce 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

Premiers pas avec Maven

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 chiers sources et construit un chier 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 spcis 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 Initialiser Traitement Prparer les rpertoires de travail

Ncessite Compiler Invoquer le compilateur javac

Ncessite Assembler Invoquer larchiveur jar

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 chier de conguration 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 conguration 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 dnit donc un scnario type de construction dun projet Java, avec des tapes cls prdnies et dont lordre est immuable. Ce "cycle de vie" est sufsamment 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 dni par une norme, chaque serveur proposant des options de conguration pour bncier dun comportement personnalis lorsque cest ncessaire. Une convention a, bien sr, un statut infrieur une norme comme JEE, mais elle apporte la mme simplication. La force des conventions est doffrir ceux qui les suivent un outil directement exploitable, sans conguration complmentaire. Une convention de Maven concerne par exemple lemplacement des chiers sources Java compiler. Notre chier pom.xml

12

Premiers pas avec Maven

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 suft de ladopter pour allger dautant notre conguration 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 conguration. Maven reposant sur un scnario type de construction de projet Java, nous navons plus besoin dindiquer la moindre commande. Il nous suft 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 chier pom.xml de Maven ne compte aucune commande de compilation et, pourtant, il se traduit au nal 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 signicative, car il ne sagit plus de dnir 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 chier pom.xml que Jason nous a crit. Tout dabord, pourquoi ce nom ? Nous avons vu que ce chier 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 conit 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

La premire partie du POM permet didentier le projet lui-mme.


Listing 1.5 : Len-tte du fichier POM
<modelVersion>4.0.0</modelVersion> <groupId>fr.noubliepaslalistedescourses</groupId> <artifactId>noubliepaslalistedescourses</artifactId> <version>0.0.1-SNAPSHOT</version>

Llment modelVersion permet de savoir quelle version de la structure de donnes "modle de projet" est reprsente dans le chier XML. Les futures versions de Maven pourront ainsi exploiter des versions diffrentes de modles en parallle et introduire si ncessaire des volutions dans le format de ce chier. Lidentiant de groupe (groupId) permet de connatre lorganisation, lentreprise, lentit ou la communaut qui gre le projet. Par convention, on utilise le nom de domaine Internet invers, selon la mme logique que celle gnralement recommande pour les noms de package Java. Lidentiant de composant (artifactId) est le nom unique du projet au sein du groupe qui le dveloppe. En pratique et pour viter des confusions, il est bon davoir un artifactId unique indpendamment de son groupId. Enn, on prcise quelle version du projet est considre. La plupart des projets utilisent la formule <Version Majeure>.<Version Mineure>.<Correctif>, mme sil est difcile dobtenir un consensus sur la signication exacte de ces numros et sur leur emploi. Vous pouvez utiliser une chane arbitraire, mais la syntaxe numrique permet de faire des comparaisons de versions et de trier celles-ci pour identier automatiquement la plus rcente. SNAPSHOT est un mot cl rserv de Maven, dont nous dcrirons la fonction par la suite.
ASTUCE Le numro de version est un concept dlicat et changeant selon les organisations et la sensibilit de chacun. Nous vous recommandons une notation purement numrique qui facilite les comparaisons, selon la logique Majeur.Mineur.Correctif. Seules deux versions majeures peuvent ne pas assurer de compatibilit, une nouvelle version mineure peut apporter des fonctionnalits indites mais sinterdit de ne pas respecter le mode de fonctionnement existant ; enn, une version corrective napporte aucune fonctionnalit nouvelle mais limine certains problmes. Certains enrichissent cette numrotation dun dernier lment qui indique le degr de conance dans une version donne : "RC" pour une Release Candidate (version quasi nale), "GA" pour General Availability pour une version diffuse au public. Cet usage peut porter prjudice au projet car dans la comparaison purement alphabtique, "GA" est infrieur "RC" !

14

Premiers pas avec Maven

Partie I

La deuxime partie du POM concerne la construction du projet :


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

Lapproche dclarative utilise par Maven permet de dnir lemplacement de nos chiers sources. Le projet tant la fois trs simple et trs banal, aucune autre dclaration nest ncessaire. Si nous avions utilis le rpertoire conventionnel de Maven pour les chiers sources Java, nous naurions mme pas eu besoin de ce bloc <build> ! La troisime partie de POM concerne les bibliothques dont dpend le projet :
Listing 1.7 : Le bloc dependencies du fichier POM
<dependencies> <dependency> <groupId>javax.mail</groupId> <artifactId>mail</artifactId> <version>1.4</version> </dependency> <dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>1.4</version> </dependency> <dependencies>

Une nouvelle fois, lapproche dclarative prend le dessus : nous nindiquons pas lemplacement physique de ces bibliothques, savoir /lib pour notre projet, mais des identiants groupId + artifactId + version. Il sagit des mmes identiants 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 able, plutt que de se contenter des chiers 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

Pourquoi adopter ces conventions ? Nous venons de le voir, Maven propose un ensemble de conventions qui permettent doutiller le projet avec peu de conguration. Il ne nous interdit cependant pas de choisir nos propres conventions, comme le rpertoire src pour les sources du logiciel. Dans ce cas, pourquoi adopter les conventions de Maven, alors quil suft de quelques lignes de dclaration supplmentaires pour "plier" Maven nos habitudes ? Hostiles au changement, comme une grande majorit des tres humains, nous prfrons cette option. Cest ce moment quEmmanuel se propose de nous rejoindre, lui aussi temps perdu grce son boulot en or, pour enrichir notre projet dun grand nombre de nouvelles fonctionnalits. Emmanuel est dj habitu Maven et peut donc tre rapidement productif et nous aider le congurer correctement. Seulement, les choses ne se passent pas aussi simplement que prvu, car malgr son exprience de loutil, Emmanuel ne retrouve pas ses petits : pour ajouter des tests notre architecture, il doit crer un nouveau rpertoire de sources, indpendant de celles du projet. Or notre rpertoire src na quun seul niveau et ne permet pas de diffrencier le livrable des tests. Il est donc oblig de dclarer une nouvelle drogation aux conventions de Maven. Par ailleurs, mme si les diffrences sont minimes, il est contraint dadapter toutes ses petites habitudes notre structure de rpertoire, qui nest pas "strictement conforme Maven". Les conventions de Maven ne sont pas obligatoires, cependant rchissez deux fois avant de vouloir en imposer dautres pour votre projet. Dune part, vous allez vous compliquer inutilement la tche en ne protant pas du comportement par dfaut que propose Maven, et chaque nouvelle option active pourra se traduire par une nouvelle phase de conguration. moins dtre passionns par lditeur XML, peu de dveloppeurs prennent du plaisir perdre un temps prcieux dans des chiers de conguration, Maven ou autres. Ensuite, pensez la gestion de vos quipes et lintgration de nouveaux dveloppeurs. Maven offre loccasion de dnir une fois pour toutes la structure de tous vos projets Java, de manire homogne. Un dveloppeur pourra passer dun projet un autre sans perdre son temps apprendre les petites habitudes locales : o sont les chiers de conguration ? Dans quel rpertoire place-t-on les donnes de test ? Tous les projets qui se conforment aux conventions Maven seront identiques de ce point de vue, et le dveloppeur sera plus rapidement productif.

16

Premiers pas avec Maven

Partie I

Enn, 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 l 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 difcilement 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. Enn, 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 spciques 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 simplis. Un dveloppeur, issu dun contexte trs diffrent mais dj utilisateur de loutil, peut prendre le projet en main sans difcult 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 conits lorsque deux personnes travaillent sur le mme chier. 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 chiers 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

Premiers pas avec Maven

Partie I

base sur Wicket et, enn, 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 chiers JAR avec des noms plus ou moins htroclites. Les choses se compliquent alors signicativement 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 abilit de leur tlchargement. Comme il est dlicat de comparer deux versions dun chier binaire, il nous est impossible de savoir en quoi notre chier util.jar diffre de celui utilis sur un autre projet comparable, dont nous voulons importer des classes intressantes. Mme si ces deux chiers portent le mme nom et ont la mme taille, cela ne signie 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 vrication et nous nous contentons de lire le nom de larchive mail-1.2.jar pour identier 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 modi peut rendre la bibliothque inutilisable, sans parler de ces charmants petits virus qui peuvent traner un peu partout. Lidentication du problme peut tre extrmement complexe, car la remise en cause de la bibliothque sera probablement la toute dernire hypothse que nous voquerons pour justier 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.

Le tlchargement de la distribution JavaMail depuis le site de SUN 1 donne un chier ZIP contenant la fois les binaires et la documentation de cette API ; les binaires, car JavaMail regroupe en fait plusieurs archives JAR, savoir mail.jar, mais aussi
1. http://java.sun.com/products/javamail/.

Chapitre 2

Au-del de java.lang

19

mailapi.jar. La premire contient lensemble du code public JavaMail alors que la seconde ne comprend que les API de programmation, et pas la gestion des protocoles de transfert de messages (pop, smtp, imap) qui sont optionnels. Lequel utilisons-nous actuellement ? Par quoi le remplacer ?

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 modier tous nos scripts de gestion du projet (scripts de compilation et de lancement, chiers de conguration 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 vrier 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 chier mail.jar et le remplaons purement et simplement par le nouveau chier 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 modie dune bibliothque, par exemple parce quon y a intgr un correctif qui nest pas encore pris en compte dans une version ofcielle.
INFO Le format darchive JAR prvoit un chier 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 chier 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 modication des scripts.

Ce qui pourrait ressembler la solution miracle nest pas aussi parfait quil y parat. Dune part, cela ne rsout pas la conguration de notre environnement de dveloppement qui continue de rclamer une liste prcise de bibliothques inclure dans le ClassPath. Ensuite, une manipulation malheureuse de nos chiers JAR ne se verra pas

20

Premiers pas avec Maven

Partie I

immdiatement un glisser-dposer est si vite arriv ! Il faudra attendre quelle ait un impact visible pour devoir ensuite remonter lorigine du problme. Enn, ce nest pas une solution dune grande lgance. Pour viter de devoir traiter le problme, nous avons ouvert les portes en grand tout ce qui passe. Difcile de parler de "matrise" de nos bibliothques dans de telles conditions. Identication univoque Maven propose une approche loppos de ces pratiques hasardeuses. Il se focalise sur lidentication exacte des bibliothques utilises. Des rfrentiels de bibliothques sur Internet lui sont ddis et permettent de tlcharger les bibliothques prcises, utilises dans le projet, sans ambigut. Les risques derreur de transfert sont limins par un contrle automatique bas sur des fonctions de hachage (une sorte dempreinte digitale du binaire, qui sera invalide au moindre bit invalide). Lidentication dune bibliothque utilise par un projet sappuie sur un triplet ( identifiant de groupe, identifiant dartefact, version prcise), lequel est construit sur le mme principe que celui que nous avons dclar pour notre projet. Dans le chier POM de Jason, nous rfrenons lartefact mail de la bibliothque standard javaMail dans sa version 1.4.
<dependency> <groupId>javax.mail</groupId> <artifactId>mail</artifactId> <version>1.4</version> </dependency>

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 modie 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 chier. Les quipes de maintenance, confrontes ce cas de gure, auraient du l retordre. Comment grer une mise niveau ou un bogue rencontr dans la bibliothque considre si on est incapable de lidentier 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 modie, pour une quelconque raison, avec je ne sais quel impact possible sur lapplication.

Chapitre 2

Au-del de java.lang

21

Lidentication exacte rclame par Maven oblige prciser quelle version est utilise et dnir des numros de version pour chaque variante de la bibliothque ou version modie que lon voudrait utiliser. Ajouter une bibliothque un projet Maven se traduit simplement par lajout dun bloc <dependency> comparable notre exemple, identiant sans quivoque notre intention. Pas de script diter, pas de chier JAR tlcharger et donc pas de validation du chier tlcharg ; pas de rpertoire de bibliothques modier, avec les risques derreur de synchronisation qui en dcouleraient. Mettre jour une bibliothque consiste tout simplement modier 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 conguration 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 l 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>

Pour notre dpendance JavaMail, nous obtenons : http://repo1.maven.org/maven2/ javax/mail/mail/1.4/. En plus du chier JAR de la bibliothque attendue, nous trouvons de nombreux autres chiers dans ce rpertoire :
m

Chaque chier prsent est accompagn de deux partenaires, avec respectivement lextension .md5 et .sha. Il sagit des empreintes de contrle associes au chier, que Maven exploitera pour sassurer que le chier na subi aucune altration au cours du tlchargement. Un chier porte le mme nom que la bibliothque avec le sufxe -sources. Il sagit, comme on pourrait sen douter, dune archive des sources Java de la bibliothque,

22

Premiers pas avec Maven

Partie I

ce qui pourra se montrer fort utile depuis votre environnement de dveloppement intgr prfr pour utiliser un dbogueur et parcourir le code de cette bibliothque. Il pourrait galement y avoir un autre chier avec le sufxe -javadoc contenant la documentation technique de la bibliothque.

Figure 2.1 Le sous-rpertoire ddi JavaMail 1.4 sur le dpt de bibliothques.

Un autre chier 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 chier de ce type. Soit parce que la bibliothque a t dveloppe en utilisant Maven, soit parce quun chier minimal a t crit pour fournir une description de la bibliothque aux utilisateurs de Maven. Un chier de mtadonnes, propre Maven comme son nom lindique clairement.

Avis aux amateurs de casse-tte


Notre projet, issu dun code antdiluvien auquel chacun est venu apporter sa contribution, est constitu de bric et de broc. Le rpertoire lib devient un sacr fourre-tout, et cest rellement compliqu de savoir pour quelle raison nous avons d introduire commons-net-1.3.jar dans le projet. Aucune de nos classes ne fait rfrence ce package !

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 sufse 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 proter de nouvelles fonctionnalits ou dun correctif. Nous devons retracer la main la chane complte des bibliothques pour identier 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 modications lourdes ont t apportes, limitant fortement la compatibilit, ce qui justie le changement de version. Par contre, nous pouvons tre plus conants 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 didentier 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

Premiers pas avec Maven

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 enn le mystrieux util.jar qui sest avr tre Apache commons-io. Le chier 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 chiers POM et des chiers JAR comme sil ne tlchargeait pas dj assez de choses ! Ces chiers 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 chier 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 difcile 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 conit 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
Hibernate-entitymanager Spring-context

Dpendances de la dpendance

Dpendances de la dpendance

Version : 3.3.1.GA Hibernate-core Version : 1.0.4 Commons-logging

Spring-core

Version : 1.1

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 conits 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 congurable de dpendance, qui permettra de choisir une politique de gestion de conit, par exemple pour faire face des numros de version exotiques pour lesquels Maven est incapable deffectuer correctement une comparaison.

Cette dernire fonctionnalit nit par nous convaincre dnitivement. 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

Premiers pas avec Maven

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 chiers 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 modication, 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 abiliser 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, identi lors de la migration du projet sous Maven !

Chapitre 2

Au-del de java.lang

27

Cela se complique. Peut-tre quavec un troisime sous-rpertoire dans /lib Stop ! Fini de jouer, interrompt Jason, avant de nous expliquer comment Maven traite de manire globale ce problme. Les "scopes" Notre problme vient de la ncessit dassocier chaque dpendance du projet le contexte dans lequel elle doit intervenir. Sagit-il dun lment indispensable lexcution du logiciel ? Est-il utilis uniquement des ns de test ? Doit-il tre inclus dans lapplication ou est-il intgr dans lenvironnement dexcution ? La dclaration dune dpendance Maven permet de dnir un lment supplmentaire, le "scope" dans lequel la dpendance devra sappliquer. Nous pouvons ainsi prciser que la bibliothque jUnit nest utilise que durant la phase de test et que lAPI servlet ne doit pas tre intgre dans notre archive web.
<dependency> <groupId>javax.servlet</groupId> <artifactId>servlet</artifactId> <version>2.3</version> <scope>provided</scope> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.7</version> <scope>test</scope> </dependency>

Maven exploite ces donnes supplmentaires lorsquil excute les commandes de construction du projet. Avec cette prcision, jUnit ne sera pas inclus sur la liste des bibliothques rfrences par la commande de compilation. Maven aurait ainsi identi notre bogue immdiatement.

Une arme double tranchant


La facilit avec laquelle Maven permet de marier les bibliothques, grant dpendances et conits, nous retire une (autre) sacre pine du pied. Nous pouvons ainsi nous focaliser sur le dveloppement du logiciel sans tre frein par dennuyeux problmes techniques lis aux bibliothques. Notre application de gestion de liste de courses stoffe donc rapidement. Elle contient dsormais des frameworks de toutes sortes comme Spring, Hibernate, Apache CXF ou Wicket pour prendre en charge les diffrents aspects de notre architecture.

28

Premiers pas avec Maven

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 chiers POM de chacune. La qualit de ces informations est dterminante pour obtenir une gestion ne 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 chier 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> ...

Llment <optional> permet de prciser la version de la bibliothque pour laquelle le projet a t conu, mais que son utilisation nest pas ncessaire et ne correspond qu un cas particulier. Pour le malheur de nombreux utilisateurs, les dveloppeurs de commonslogging ont cependant "oubli" de prciser ce caractre optionnel jusqu la version 1.1.1. Cest pour cette raison que nous retrouvons avalon-framework-4.1.3.jar dans nos bibliothques.

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 dnir des dpendances ables. 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 modier un POM qui a t publi, en raison du grand nombre de miroirs et de caches utiliss par la communaut : un chier modi signierait 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 dnissons 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>

Un autre problme que nous avons identi est ce doublon commons-logging + commons-logging-api. Ce cas est plus subtil. Les dveloppeurs de commons-logging proposent leurs utilisateurs une srie de classes qui masquent dautres outils de log. Leur projet est donc spar en une API et des adaptateurs vers chaque outil support. Pour viter certains dutiliser par mgarde une classe dun adaptateur et pas seulement celles de lAPI, ils ont mis disposition une archive JAR ne contenant que les classes utilisables par les dveloppeurs : commons-logging-api. L o les choses se corsent, cest que ces mmes classes se retrouvent dans le commons-logging classique, et Maven nest pas en mesure de le deviner. Aussi, de son point de vue, il sagit de deux dpendances indpendantes pour lesquelles aucune rgle de conit ne peut sappliquer. Il nexiste malheureusement aucune solution miracle pour indiquer quune bibliothque donne est en ralit un sous-ensemble dune autre et grer des conits de

30

Premiers pas avec Maven

Partie I

version entre elles. Une gestion propre du dveloppement de la bibliothque aurait d aboutir la sparation de commons-logging-api et dun second artefact complmentaire, mais pas redondant. vouloir rpondre aux demandes contradictoires des utilisateurs (un seul JAR avec tout le ncessaire, des JAR focaliss sur un aspect donn) le projet perd en cohsion et les utilisateurs rencontrent au nal des difcults quon aurait d leur pargner. Nous avons vu que les <exclusions> permettent de corriger ces erreurs de mtadonnes. Reste faire le tri dans nos dpendances pour trouver ces erreurs. Dans notre cas, nous voulons conserver commons-logging et exclure commons-logging-api, mais aucune solution automatique nest possible. Lanalyse des dpendances Avec le nombre de frameworks que nous avons intgrs lapplication, il devient difcile de savoir qui introduit quelle dpendance. Mme si les exclusions peuvent permettre de corriger le tir, encore faut-il savoir sur quelles dpendances les dclarer. Maven propose un outillage complet pour analyser nos dpendances, via les plugins dependency et project-info-reports. La commande mvn dependency:list permet dtablir la liste des dpendances du projet, soit lquivalent de notre rpertoire WEB-INF/lib. Elle sera utile pour vrier limpact de nos exclusions au fur et mesure que nous les dclarerons. La commande project-info-reports:dependencies est analogue la prcdente mais elle gnre un chier HTML contenant la liste des dpendances. Plus intressante, mvn dependency:tree trace un arbre, o chaque branche est une dpendance qui introduit par transitivit dautres dpendances.
Listing 2.1 : Excution de mvn dependency:tree
[INFO] [dependency:tree] [INFO] fr.noubliepaslalistedescourses: noubliepaslalistedescourses:war:1.0.0-SNAPSHOT [INFO] +- org.apache.cxf:cxf-rt-frontend-jaxws:jar:2.1.4:compile [INFO] | [INFO] | [INFO] | [INFO] | [INFO] | [INFO] | [INFO] | [INFO] | +- org.apache.geronimo.specs:geronimo-jaxws_2.1_spec:jar:1.0:compile +- org.apache.geronimo.specs:geronimo-ws-metadata_2.0_spec:jar:1.1.2:compile +- asm:asm:jar:2.2.3:compile +- org.apache.cxf:cxf-rt-bindings-xml:jar:2.1.4:compile +- org.apache.cxf:cxf-rt-frontend-simple:jar:2.1.4:compile +- org.apache.cxf:cxf-rt-ws-addr:jar:2.1.4:compile +- javax.xml.soap:saaj-api:jar:1.3:compile \- com.sun.xml.messaging.saaj:saaj-impl:jar:1.3.2:compile

Chapitre 2

Au-del de java.lang

31

[INFO] [INFO] [INFO] [INFO] [INFO] [INFO] [INFO] ...

| | | +| +|

\- 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 didentier 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 chier POM.

Figure 2.3 Plugin Maven pour Eclipse.

32

Premiers pas avec Maven

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 efcace pour traiter les difcults 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.

tes-vous prt pour Java 7 ?


Le prototype lorigine de notre projet a t crit il y a belle lurette et utilise la syntaxe Java 1.2. Maven na pas de grande difcult pour le compiler, ce qui aurait t un comble. Nous sommes cependant au XXIe sicle, et la syntaxe Java 5 est dsormais le socle de base de nombreux dveloppement, en attendant que Java 7 apporte de nouvelles volutions. Une particularit du passage du cap Java 5 est que les options -source et -target du compilateur javac prennent tout leur sens pour activer le support des volutions du langage. Conants dans Maven qui, pour linstant, nous apporte entire satisfaction, nous retravaillons un peu le code historique de gestion des listes de courses pour bncier dune syntaxe moderne, alliant gnricit, autoboxing et arguments variables. Devant un code qui semble nettement plus moderne, nous lanons rement la compilation par Maven, avant de tomber sur un message derreur fort dsagrable :
[INFO] [compiler:compile] [INFO] Compiling 78 source files to D:\noubliepaslalistedescources\target\classes [INFO] -----------------------------------------------------------------------[ERROR] BUILD FAILURE

34

Premiers pas avec Maven

Partie I

[INFO] -----------------------------------------------------------------------[INFO] Compilation failure D:\noubliepaslalistedescources\src\main\java\org\ noubliepaslalistedescources\ model\MesCourses.java:[57,5] annotations are not supported in -source 1.3 (use -source 5 or higher to enable annotations)

Pardon ? Maven nest pas compatible Java 5 ? Pas de panique, les choses sont plus subtiles que cela et, heureusement pour nous, moins dnitives. 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 congur, 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 modier 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 recongurer ces tapes standard, lorsque leur fonctionnement par dfaut ne suft 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

Un peu plus que compiler

35

Plugins
Maven cone 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 chiers 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 modication des options par dfaut dun plugin seffectue dans le chier 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 recongur. Un plugin, comme tout artefact manipul par Maven, est identi par le triplet [identiant de groupe, identiant 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 difcult aux cas de gure 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

Premiers pas avec Maven

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 conguration 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 modication du fonctionnement du plugin de compilation nous permet enn de valider la syntaxe Java 5 que nous avons introduite dans le projet. Ce besoin tout

Chapitre 3

Un peu plus que compiler

37

simple a cependant ncessit une conguration signicative, ce qui peut vous laisser perplexe : pas moins de 10 lignes dans le chier POM.xml, l ou deux attributs sufsent dans un script Ant ! Ce principe de reconguration des plugins est la version "lourde" de la solution, mme si elle a lavantage de nous ouvrir les portes de toutes les options de conguration. 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 modies 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

Nous savons donc comment modier la demande la conguration utilise par le plugin de compilation sans modier le chier POM. Cela peut tre trs utile, en particulier pour modier trs ponctuellement le comportement de Maven sans toucher la conguration. Mais pour notre problme de compilation Java 5, le prix payer est lourd : la ligne de commande que nous devons taper dans une console sallonge dangereusement ! Comme les dveloppeurs de Maven sont un peu fainants comme tout bon dveloppeur, ils ont pens une solution intermdiaire pour nous viter de telles lignes de commande, sans pour autant devoir ajouter des dizaines de lignes notre chier POM : les proprits. Il sagit tout simplement de ger les variables denvironnement dans le chier POM, lintrieur dun bloc <properties>. La valeur indique sera prise en charge exactement de la mme manire par linterpolation, tout en tant encore modiable via le -D sur la ligne de commande. Cela permet de dnir en quelque sorte des valeurs par dfaut applicables sur le projet et sur lui seul :
<properties> <maven.compiler.source>1.5</maven.compiler.source> <maven.compiler.target>1.5</maven.compiler.target> </properties>

38

Premiers pas avec Maven

Partie I

La plupart des plugins Maven proposent cette option pour leurs principaux paramtres de conguration ; 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.

Quand Java ne suft plus


Bien que nous ayons introduit la syntaxe Java 5 dans notre code, Arnaud est loin dtre satisfait par sa lisibilit. Selon lui, de nombreux passages techniques pourraient tre nettement plus simples si nous renoncions la syntaxe Java ! Aprs vrication du contenu de sa tasse de caf, nous comprenons quArnaud est tout fait jeun (il faut dire quil est tout juste 9 heures du matin) et tout fait srieux. Il voque, en fait, avec un savant effet de suspens la possibilit dutiliser le langage Groovy pour coder notre application, ou tout du moins certains composants qui sy prtent trs bien.
INFO Groovy est un langage dynamique qui sexcute sur la machine virtuelle Java, au mme titre que jRuby ou Jython par exemple. Lenvironnement dexcution Java actuel ne se limite plus au seul langage de programmation Java et accueille un nombre croissant de langages via des interprteurs ou des compilateurs spcialiss. Vous pouvez par exemple dvelopper une application en PHP et lexcuter sur un serveur Java ! Ce qui pourrait sembler a priori un mariage contre nature ouvre en ralit des perspectives tonnantes, en fonction des points forts de certains langages dans des domaines prcis, ou tout simplement des dveloppeurs dont vous disposez.

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 dnir 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 suft 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 suft dajouter au

4. http://groovy.codehaus.org/GMaven.

Chapitre 3

Un peu plus que compiler

39

projet le plugin X. Lapproche dclarative de Maven conomise la dclaration des oprations ralises par le plugin et de la faon dont elles sintgrent dans le projet. O placer les sources Nous lavons dj dit, les conventions de Maven sont un lment dcisif dans sa capacit prendre en charge de manire automatise le projet. En particulier, la structure type dun projet Maven est la suivante (voir Figure 3.2).

Figure 3.2 La structure de base dun projet Maven.

La logique est plutt simple : la racine, on trouve le chier 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 conguration de votre gestionnaire de code source ! Il suft dexclure target (en plus des chiers spciques de votre IDE) et vous tes sr de ne pas inclure par mgarde des chiers 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

Premiers pas avec Maven

Partie I

Enn, dans chacune de ces branches, un dernier niveau de rpertoires spare les chiers sources par langage : java pour le code source de vos classes java, resources pour les chiers de ressources (conguration XML ou chiers de proprits), webapp pour les chiers statiques dune application web. Le plugin Groovy ajoute son lot de conventions qui viennent complter celles dj dnies par Maven. Les chiers 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 spcier la version de vos plugins. partir de Maven 2.0.9, ceux qui sont dclars par dfaut dans Maven ont une version prdnie en interne pour viter ce pige.

Au lancement de Maven, nous constatons avec plaisir le tlchargement de chiers POM et JAR associs au plugin Groovy. Voici une autre explication de la dpendance de Maven un accs Internet : les plugins, comme les bibliothques, sont tlchargs la demande depuis un dpt de bibliothques. Linstallation de Maven est ainsi

Chapitre 3

Un peu plus que compiler

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 signie 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 dnit ainsi plusieurs tches (ou goals) et il ne suft 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 dnir les tches dnies par le plugin considr que Maven devra excuter. Miracle, nous pouvons compiler notre code source Groovy. Sortez la boule facettes !

42

Premiers pas avec Maven

Partie I

Construction du projet

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 d 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 ches 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

Un peu plus que compiler

43

raction pidermique face lampleur de la tche, Nicolas lche son arme secrte : GWT.

Figure 3.4 Notre document ofciel de spcications 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 nalement 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

Premiers pas avec Maven

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>

Comme pour lintgration de Groovy, nous navons au niveau du projet Maven qu ajouter lidentiant exact du plugin utilis, dnir une ventuelle conguration si les valeurs par dfaut ne nous conviennent pas, et prciser dans une <execution> quelles tches doivent tre excutes lors de la construction du projet. En consultant la documentation du plugin GWT5, nous dcouvrons quelque chose qui nous intresse : la tche eclipse du plugin propose de gnrer automatiquement des scripts de lancement pour excuter directement lapplication web depuis notre environnement de dveloppement au moins pour ceux dentre nous qui utilisent Eclipse ! Nous ajoutons cette tche notre execution, et nous lanons en toute conance un mvn install :
... [INFO] ----------------------------------------------------------------[INFO] BUILD SUCCESSFUL [INFO] ----------------------------------------------------------------INFO] Total time: 50 seconds

Voil qui est encourageant mais pas de script de lancement offrir notre Eclipse. Rien dtonnant cela : la conguration 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

Un peu plus que compiler

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 conguration de lenvironnement de dveloppement. La plupart des plugins et des tches quils dnissent 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 quali de "projet type" utilis par Maven pour identier 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 dnir les tapes cls de la construction du projet.

46

Premiers pas avec Maven

Partie I

On retrouve ainsi :
Tableau 3.1 : Le cycle de vie dni par Maven

Phase validate initialize generate-sources process-resources compile process-classes test-compile test package install deploy

Description validation du projet Maven initialisation gnration de code source traitement des fichiers de ressources compilation des fichiers sources posttraitement des fichiers binaires compils compilation des tests excution des tests assemblage du projet sous forme darchive Java mise disposition de larchive sur la machine locale pour dautres projets mise disposition publique de larchive java

Il sagit dune liste simplie : le cycle complet dnit 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

Un peu plus que compiler

47

Tableau 3.2 : Les plugins et les tches associs par dfaut au cycle de vie dun projet JAR

Phase process-resources compile process-test-resources test-compile test package install deploy

Plugin maven-resources-plugin maven-compiler-plugin maven-resources-plugin maven-compiler-plugin maven-surefire-plugin maven-jar-plugin maven-install-plugin maven-deploy-plugin

Tche Resource Compile testResources testCompile Test Jar Install Deploy

Maven fournit un moyen pour venir greffer dautres plugins ce cycle, en plus de ceux quil aura associs par dfaut.

Phases validate generate-sources generate-resources process-resources compile process-classes test-compile test package integration-test verify install deploy

Plugins gwt:generateAsync

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

Premiers pas avec Maven

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 chier 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 difcile 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 modies ? 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 signie pas pour autant que Maven rende un systme documentaire inutile. Cependant, autant que possible, automatisez et simpliez les choses et ayez plutt le rexe 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

Un peu plus que compiler

49

le rpertoire target est ddi tous les chiers intermdiaires de la construction du projet. Maven considre que des chiers gnrs ne sont pas des chiers sources, mme sils sont crits dans la syntaxe du langage Java. Le chier source est le contrat WSDL qui permet de les produire. Rien ninterdirait loutil de gnration de produire directement du code binaire dans des chiers class (si ce nest que cest nettement plus compliqu). Il ny a donc aucune raison de placer ce code gnr dans notre arborescence src. Le plugin cxf-codegen associ notre pile de services web Apache CXF sait prendre en charge la procdure de gnration de code. Il sassocie la phase generate-source du cycle de vie qui est prvue pour ce type de plugins. Il prend en paramtre les chiers WSDL traiter et les options de gnration ; aussi plaons-nous notre chier WSDL dans un rpertoire de ressources ddi ce format : src/main/resources/wsdl.
<plugin> <groupId>org.apache.cxf</groupId> <artifactId>cxf-codegen-plugin</artifactId> <version>2.2</version> <executions> <execution> <goals> <goal>wsdl2java</goal> </goals> </execution> </executions> <configuration> <defaultOptions> <noAddressBinding>true</noAddressBinding> </defaultOptions> </configuration> </plugin>

Le code gnr par ce plugin est plac dans le rpertoire target/generated-sources/ cxf. Il sagit galement dune convention de Maven, qui permet chaque plugin gnrateur de code davoir son propre rpertoire de gnration tout en conservant une certaine cohrence. Ces rpertoires sont automatiquement ajouts dans le chemin de compilation du projet et seront donc pris en considration lors de la phase de compilation qui suit. La stratgie utilise par Maven pour les gnrateurs de code rsout donc nos deux problmes : la procdure de gnration na tout simplement plus besoin dtre documente. Elle est systmatiquement excute, ce qui a lavantage non ngligeable de nous assurer la totale cohrence entre le chier source qui sert cette gnration et qui seul fait foi, et le code qui en est driv et est utilis par lapplication. Ensuite, une modication du code gnr est tout simplement impossible, celui-ci ntant pas sauvegard dans le gestionnaire de sources. Il vous suft gnralement dtendre les classes

50

Premiers pas avec Maven

Partie I

gnres pour dvelopper le code propre votre application, plutt que de venir modier ce code et de risquer de tout perdre lors de la gnration suivante, ou de devoir comparer deux versions et reporter manuellement vos modications. 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 chier qui sert de rfrence a t modi.

Produire autre chose quun JAR


Amus par notre interface web en GWT, Franois se joint notre quipe. La particularit de Franois est quil nest pas seulement un dveloppeur Java, mais aussi un spcialiste de la plateforme Flex dAdobe. Il dcide donc de nous dvelopper une interface web faisant appel toute la richesse du plugin Flash. Comme pour les cas prcdents, nous dcouvrons avec plaisir quil existe un plugin Maven, le projet Flex-mojos7, qui prend en charge la compilation spcique des sources Flex. Cependant, Flex nest pas Java, et une application Flash sassemble sous forme dun chier SWF qui na pas grand-chose en commun avec un JAR. Il ne sufra donc pas dajouter notre chier POM des dclarations de plugins, il faut compltement changer le cycle de vie et les plugins par dfaut utiliss par Maven. Ce cycle de vie par dfaut est slectionn par Maven en fonction de llment <packaging> de notre POM, qui prend par dfaut la valeur jar. Nous pouvons tout aussi bien lui donner la valeur war pour construire une application web, ou ear pour une archive dentreprise (voir Chapitre 8). Pour crer une application Flash, nous allons utiliser le packaging SWF. Cette valeur nest, bien sr, pas comprise par Maven sans un peu daide. Maven est conu pour tre fortement extensible, aussi lassociation du packaging avec un cycle de vie est ralise lexcution et peut tre assiste par des complments, appels extensions. Un plugin peut lui-mme apporter des extensions : cest le cas du plugin ex-mojos.

7. http://code.google.com/p/ex-mojos.

Chapitre 3

Un peu plus que compiler

51

Le chier 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 de rpertoire de sources et de tests, propre au langage Flex quil utilise. 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 spcier 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

Premiers pas avec Maven

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 chier 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.

Des plugins pour tout ?


Dans les exemples que nous venons de voir, nous avons fait appel diffrents plugins utilisant des identiants de groupe varis. Le plugin de compilation est dvelopp dans le cadre de Maven lui-mme et porte donc lidentiant de groupe org.apache.maven.plugins. Quelques plugins de base sont galement dans ce cas, et leur documentation est accessible sur le site de Maven9.
9. http://maven.apache.org/plugins.

Chapitre 3

Un peu plus que compiler

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 lidentiant 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 spciques 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>

De trs nombreux plugins vivent indpendamment, dvelopps sur les services dhbergement SourceForge, Googlecode, Java.net ou par des socits qui le diffusent depuis leur propre site web. Il nen existe pas dindex ofciel ou de catalogue toujours jour vous permettant de trouver la perle rare. Votre moteur de recherche prfr est souvent votre meilleur ami, associ au forum des utilisateurs de Maven.

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 conguration 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 difcult : 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 simplier, lassouplir, le rendre extensible, adaptable, bref : meilleur. Ce travail ncessite cependant de sassurer que les services rendus resteront les mmes aprs ces modications. 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 vrier les ventuelles erreurs et incompatibilits que nous pourrions introduire involontairement. Nous passons donc beaucoup de temps tester lapplication an de voir si elle continue de fonctionner "comme avant".

Tester ? Pour quoi faire ?


Tester un logiciel est un travail rptitif, souvent ennuyeux, mais pourtant indispensable. Nous devons videmment vrier que la toute dernire volution fonctionne comme prvu, ce qui est relativement motivant. Nous devons galement par la mme occasion nous assurer que tout le reste de lapplication na pas perdu en stabilit. Un effet de bord peut tre dvastateur, et un bogue rapidement introduit. Et bien souvent leur cause se cache dans une modication qui semble minime au premier abord.

56

Premiers pas avec Maven

Partie I

Une gestion de la qualit du logiciel doit prendre bras-le-corps la problmatique des tests. Chaque version doit proposer une srie de vrications effectuer pour valider les nouveaux dveloppements, mais aussi inclure lensemble des tests identis pour les versions prcdentes, an de sassurer que lapplication ne rgresse pas. Il ne faudrait pas casser quelque chose qui fonctionnait dans la version prcdente. Une fonctionnalit qui disparat ou se dgrade dans la version suivante, cest autant dutilisateurs mcontents. Sans compter les nombreuses heures perdues identier le problme et lui trouver une solution acceptable dans lurgence : souvent un simple compromis avec la solution "idale" que lon aimerait mettre en place mais qui ncessiterait trop de travail ou introduirait de nouveaux risques. Cependant, passer des tests a un cot, surtout si lon accumule les tests ajouts par de nombreuses versions du logiciel. Reposer sur le seul humain pour cette tche, cest sexposer de nombreux risques :
m

Le cot du passage des tests, considrant la main-duvre employe plein-temps cette tche. Le temps de raction lorsquun problme a t introduit par une modication. Plus tard on sen rendra compte, plus la correction apporter sera dlicate. 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 efcace : 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 vrier. 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

Mettre en place des tests unitaires

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 vrier le fonctionnement de la classe qui la dnit, 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 chier 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 identier 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 simplie 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

Premiers pas avec Maven

Partie I

Listing 4.2 : Utilisation dune bibliothque utilitaire dans le test


/** Test automatique de la classe ListeDeCoursesReader */ public static void main( String args[] ) { ListeDeCoursesReader reader = new ListeDeCoursesReader(); ListeDeCourses attendu = new ListeDeCourses( ... ); ListeDeCourses lu = reader.read( new FileInputStream( "./test.list" ) ); if ( new BeanComparator().compare( attendu, lu )!= 0 ) { System.err.println( "FAILED: Donnes lues incorrectes" ); System.exit( -1 ); } }

Trs ers 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 simplier 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 sufxe "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

Mettre en place des tests unitaires

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 vrication du bon fonctionnement du logiciel. Loutillage de test se charge didentier tous les tests excuter et de les enchaner, en fournissant au nal 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

Premiers pas avec Maven

Partie I

Les tests sous Maven


Maven ne fait pas de choix entre ces trois outils de test. Plus prcisment, il choisit les trois plus tous ceux venir qui pourraient devenir les standards de demain. Lintgration des tests sous Maven saccommode de la bibliothque de tests que vous dclarez comme dpendances de votre projet et elle sadapte en consquence, en tlchargeant les autres dpendances adquates. Nos tests sont dsormais entirement automatiss avec laide de notre framework prfr. Reste les intgrer dans la construction du projet. En effet, lintrt de ces tests automatiss est quils sont automatiss, donc contrlables tout moment pour le seul cot du temps quils ncessitent pour sexcuter. La logique la plus lmentaire en termes de qualit logicielle est que ces tests doivent tre excuts et ne dtecter aucune erreur avant que soit produit le binaire livrable nos utilisateurs. Maven rejoint totalement cette logique et fait mme des tests un lment de premier plan du projet, au mme niveau que le code de lapplication lui-mme. Pour suivre la logique des outils de test comme jUnit ou TestNG, Maven dnit deux rpertoires dans la structure de chiers du projet : src/main/java pour le livrable, src/test/java pour les tests. La sparation entre classes du projet et classes de test qui loutillent est ainsi directement porte par lemplacement physique des chiers sources. Notre test jUnit ListeDeCoursesReaderTest est donc plac dans larborescence src/ test/java. Il ne nous reste qu lancer la commande mvn test pour constater que Maven prend bien en charge la compilation et lexcution du test. Cependant, notre ListeDeCoursesReaderTest comprend encore une faiblesse notable : il fait appel un chier pour alimenter la classe teste. Comment obtenir le chemin de ce chier de manire totalement indpendante de lenvironnement ? Il est videmment exclu de donner un chemin en dur "C:/Utilisateurs/Nicolas/test/liste.list" qui serait assez dsastreux sur une machine non Windows ou sur un autre poste de travail qui ne serait pas organis de la mme manire. Nous avons donc utilis un chemin relatif "test/liste.list", en supposant implicitement que le test serait lanc depuis la racine du projet o est plac ce chier. Si cela fonctionne assez souvent, nous sommes cependant un peu optimistes. Cest la raison dtre du rpertoire src/test/resources. Celui-ci permet de stocker toutes nos donnes de test et dy avoir accs lexcution du test via le ClassPath. Le Listing 4.4 montre lvolution de notre code de test pour accder ce chier de cette manire. Tous les chiers de donnes que nous utiliserons pour nos tests seront placs sous src/test/ resources. Ils seront ainsi intgr au ClassPath de test, mais exclus du binaire nal.

Chapitre 4

Mettre en place des tests unitaires

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 simplier 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 conance 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 dnis : 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

Premiers pas avec Maven

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 efcace 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 modication" savre bien plus signicative 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 chier dans lequel nous stockons la liste de courses. Cette modication permettra de stocker des donnes complmentaires, dont je vous laisse le soin dimaginer lutilit. Nos tests existants permettront de vrier 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 chier, il commence crire une nouvelle mthode de test vriant 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 afcher 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 efcace en termes de

Chapitre 4

Mettre en place des tests unitaires

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 qualier dans un vocabulaire plus traditionnel dexpression de besoin, Vincent est content de voir son test chouer : le test est valide et vrie bien quelque chose que lapplication ne fournit pas encore. Ne riez pas, trop souvent des tests ne font quefeurer 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 enn 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 didentier 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 able, aussi Vincent applique le second commandement du dveloppement pilot par les tests : DRY (Dont Repeat Yourself "Tu ne te rpteras pas").

64

Premiers pas avec Maven

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 modication 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 modication que nous lui apporterons an den amliorer la qualit pourra tre valide dun point de vue des fonctions rendues par lapplication : nos tests doivent tous rester au vert. Certaines modications lourdes et pourtant importantes nauraient jamais t ralises en conance sans cette garantie.
crire un test pour une fonctionnalit
Rouge

Ringnierie du code, sans ajout de fonctionnalit - le test doit toujours passer

Ringnierie

Vert

crire juste ce quil faut de code pour que le test passe

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 efcace ncessite une culture du test automatis pour tre rellement efcace. 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 plani pour prfrer une approche ractive. Voir http://fr.wikipedia.org/wiki/Mthode_agile.

Chapitre 4

Mettre en place des tests unitaires

65

Pas de JAR sans tests russis Le passage des tests par Maven fait partie des phases standard de construction du projet. Maven les place au cur de la gestion de la qualit et fait le choix de bloquer la construction du projet si un test choue. Comme ces tests sont excuts avant que la phase de packaging qui construit le JAR ne soit excute, Maven interdit donc de construire un livrable qui ne passe pas avec succs tous les tests dnis par le projet. Cest une interprtation rigoureuse des principes de qualit logicielle mais qui vite dutiliser par mgarde un JAR frachement compil et de dcouvrir de manire dtourne et coteuse un bogue qui est dj contrl par un test unitaire. Interdire la construction du JAR, nest-ce pas un peu abrupt comme prise de position ? Cest en tout cas lavis de Fabrice, qui tue le temps dans le TGV en testant rapidement quelques nouvelles ides et qui ne parvient pas lancer lapplication. Ses modications, ralises en mode "exploratoire", ne visent qu tester un nouveau concept et certainement pas obtenir un rsultat stable et irrprochable. Maven met certes les concepts de qualit logicielle au premier plan mais ne manque cependant pas de pragmatisme. Il existe une option qui permet de ne pas passer les tests lors de la construction du projet, et donc de passer outre cette rgle parfois trop stricte. Cette option, ajoute sur la ligne de commande, est DskipTests. Cest une option double tranchant, soyez-en bien conscient. Elle peut tre indispensable, comme le pense Fabrice qui peut ainsi vrier la pertinence de son ide, auquel cas il pourra la prsenter son client larrive de son voyage daffaires. Cest une option dangereuse si elle est trop utilise et que nos tests automatiss ne soient plus excuts. Rutiliser notre outillage de test Au fur et mesure de lcriture des tests, nous avons d dvelopper des classes utilitaires qui nont de sens que dans le cadre des tests : code bouchon et simulateurs, mcanisme de contrle et autres constituent un outillage complet ddi notre code an que nous soyons en mesure de le tester convenablement. En marge de notre projet, Lukas se lance dans un autre projet exprimental pour proposer une version sur tlphone mobile de notre application une cible de choix quil ne faut pas ngliger ! Lukas est rapidement confront un problme simple : dans son environnement de dveloppement, il dispose des deux projets et peut donc coder les tests de son projet noubliepaslalistedescourses-on-android en rutilisant nos utilitaires de test. Cet outillage lui simplie grandement la tche et lui permet dcrire des tests pertinents et lisibles en un temps record. Seulement, lorsquil tente de construire son projet avec

66

Premiers pas avec Maven

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 dnit et pas en dehors. Le projet de Lukas ne peut donc exploiter que les classes qui sont destines linclusion dans le JAR nal, 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 dnit 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 conguration associe au plugin jar pour obtenir ce rsultat. Le fonctionnement par dfaut suft notre besoin, aussi lajout de ce traitement ne ncessite aucun lment de conguration 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

Mettre en place des tests unitaires

67

lartefact principal du projet et des rsultats secondaires de ce type sappuie sur un sufxe ajout au nom de lartefact, ce que dans le vocabulaire Maven on nomme un classier. La tche test-jar va construire un artefact nomm noubliepaslalistedescourses-1.0-SNAPSHOT-tests.jar. Maven peut tre congur pour produire plus dun artefact lors de la construction du projet et le classier permet de diffrencier les artefacts secondaires du principal rsultat de la construction. Il est ainsi possible de construire non seulement le JAR du projet, mais aussi le JAR de ses tests, le JAR de son code source ou le JAR de sa documentation JavaDoc. Chacun de ses artefacts secondaires pourra tre rfrenc comme une dpendance en ajoutant linformation de classier adquate, comme le montre le Listing 4.6 qui prsente le POM du projet de Lukas.
Listing 4.6 : Utilisation dune dpendance exploitant la notion de classifier
<project> <modelVersion>4.0.0</modelVersion> <groupId>fr.noubliepaslalistedescourses</groupId> <artifactId>noubliepaslalistedescourses-on-android</artifactId> <version>1.0-SNAPSHOT</version> <description> Projet annexe de noubliepaslalistedescourses pour un client sur tlphone mobile Androd </description> <dependencies> <dependency> <groupId>fr.noubliepaslalistedescourses</groupId> <artifactId>noubliepaslalistedescourses</artifactId> <version>1.0-SNAPSHOT</version> </dependency> <dependency> <groupId>fr.noubliepaslalistedescourses</groupId> <artifactId>noubliepaslalistedescourses</artifactId> <version>1.0-SNAPSHOT</version> <classifier>tests</classifier> <type>test-jar</type> <scope>test</scope> </dependency> </dependencies> </project>

Lintgration continue
Nous lavons vu, nos tests automatiss prennent toute leur valeur lorsquils sont excuts rgulirement. Chaque dveloppeur peut compter sur eux pour vrier quil na pas (ou au moins, pas trop, en fonction de la qualit des tests) dtraqu lapplication avec ses

68

Premiers pas avec Maven

Partie I

dernires modications. Cela peut mme laider identier 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, an de dtecter le plus vite possible une erreur introduite par un dveloppeur qui naurait pas identi le problme par lui-mme. Il ne sagit pas du tout de rechercher le mouton noir qui introduit des bogues et ne vrie rien sur son environnement. Il nest pas rare de crer des instabilits parce quon a oubli de diffuser un chier sur le gestionnaire de version ou parce quun fragment de code dpend de lencodage des chiers 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 modications pour signaler aux personnes concernes le problme identi. 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 identier au plus tt les dfaillances de vos collaborateurs et les faiblesses de votre application, vous constaterez rapidement ses bnces 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

Mettre en place des tests unitaires

69

Son principal point faible est son interface web qui ne bncie pas des rafnements auxquels nous ont habitus les applications web modernes. Un peu trop de conguration 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 difcile 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

Premiers pas avec Maven

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 vrier que la compatibilit est au rendez-vous. Ce ne sont pas les seuls critres retenir. Nous navons vu ici quune utilisation trs supercielle 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

Mettre en place des tests unitaires

71

Les possibilits dextension et de conguration de ces serveurs sont nombreuses et rpondent des usages et des rgles de fonctionnement trs varis.

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 l 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 modie 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 vrier et valider chaque parcelle de notre application.

Des tests unitaires de moins en moins unitaires


Vous vous rappelez peut-tre que nous avons choisi Google Web Toolkit pour la ralisation de notre site web. Ce choix nous a donn entire satisfaction jusquici. lheure de lui appliquer notre stratgie de test, Nicolas se rjouit de constater que la classe GWTTestCase nous y aide grandement : il nous suft de btir nos tests dessus pour pouvoir valider le fonctionnement de cette couche. Aprs quelques jours, nous devons cependant dchanter. La construction complte du projet est passe de huit minutes plus de trente ! Les tests de notre interface web sont trs longs excuter, sans pour autant que le contenu du test puisse tre incrimin. Nicolas, qui ny est pourtant pour rien, sent monter la grogne des dveloppeurs, lasss dattendre de longues minutes la n de la construction du projet cause de ces tests qui nen nissent pas.

74

Premiers pas avec Maven

Partie I

La rponse vient de la structure particulire de ces tests utilisant GWT : lquipe de dveloppement de Google offre un mcanisme de test qui sintgre bien dans nos habitudes bases sur jUnit ; cependant, pour en arriver l, ils ont d jongler avec des contraintes contradictoires. Un test GWT ncessite une phase de compilation spcique du code de lapplication, lmulation dun navigateur web, en plus du lancement dun serveur HTTP, comme le montre la Figure 5.1. Ces deux tapes sont trs lourdes et ralentissent considrablement lexcution du test. La phase de prparation du test peut ainsi rapidement occuper beaucoup plus de temps que lexcution du test lui-mme. Ce problme, multipli par de nombreux tests sur le mme modle, a des consquences immdiates sur le temps de construction de notre projet.
Arrt du navigateur et du serveur embarqu

Dmarage du navigateur web headless (sans visuel) Dmarage du micro-serveur embarqu

Lancement du module GWT complet Excution du test

Lancement du test

Temps utile

Test termin

Figure 5.1 La squence dopration droule par un test GWT.

Impatients dobtenir le rsultat de leur travail, les dveloppeurs prennent peu peu lhabitude dutiliser loption skipTests ( mvn install -DskipTests=true ). Celle-ci est bien pratique, parfois mme indispensable, mais elle devrait tre lexception et non la rgle dans lutilisation courante de Maven. Herv se dsole de voir que les bonnes pratiques peine acquises sont si rapidement oublies. Il doit pourtant bien reconnatre que loutillage de test unitaire ne peut tre pertinent que sil est rapide excuter. Quest-ce quun test "unitaire" Quand nous parlons de tests unitaires, nous considrons des tests simples, cibls, excuts dans un environnement lger et totalement sous contrle. Ces tests sont ligibles une excution systmatique car ils peuvent tre excuts rapidement, sans ncessiter de prparation particulire de la machine.

Chapitre 5

Mettre en place des tests dintgration

75

Avec cette dnition, 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 prol de Maven offre une solution simple pour que chaque dveloppeur puisse activer les spcicits qui conviennent sa tche en cours, sans perdre le bnce davoir toute la conguration et tout loutillage ncessaire (ou du moins le maximum) congurs dans le seul chier POM.

Les prols
La rponse de Maven ce problme sappelle un prol. Il sagit tout simplement de regrouper tout ce qui implique un pan de construction que nous voulons rendre optionnel. Dni au sein dun bloc ddi, il pourra au besoin tre activ ou dsactiv selon le dveloppeur qui intervient sur le projet. Le prol peut dnir 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 conguration dun prol qui excutera nos tests GWT si le prol associ est activ. Notez la conguration 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 prol 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

Premiers pas avec Maven

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 bncier 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 prols spars par une virgule permet dactiver la demande les prols dsirs par lutilisateur. Sadapter lenvironnement Une autre utilisation des prols consiste adapter la conguration Maven du projet lenvironnement de lutilisateur. Il est aussi possible de conditionner lactivation du prol une spcicit de lenvironnement dexcution, par exemple le systme dexploitation ou la version de Java qui excute Maven. Une proprit systme (dnie avec loption -Dnom=valeur de la ligne de commande) peut aussi servir de condition pour activer un prol. Enn, le prol peut tre activ en fonction de la prsence dun chier 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 prols pour tablir une liste de dpendance par type de systme.

Chapitre 5

Mettre en place des tests dintgration

77

Le Listing 5.2 montre un autre cas dactivation dun prol 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

Premiers pas avec Maven

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 prol 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 justier dans certains cas. Un prol 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 conguration de ce type. La commande suivante permet de droger cette rgle le temps dune excution de Maven :
mvn -P!codestyle install

Listing 5.3 : Profil contrlant le respect des rgles de codage


<profile> <id>codestyle</id> <activation> <activeByDefault>true</activeByDefault> </activation> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-checkstyle-plugin</artifactId> <version>2.2</version> <executions> <execution> <phase>validate</phase> <configuration> <configLocation>checkstyle.xml</configLocation> <consoleOutput>true</consoleOutput> <failsOnError>true</failsOnError> <linkXRef>false</linkXRef> </configuration> <goals> <goal>checkstyle</goal> </goals>

Chapitre 5

Mettre en place des tests dintgration

79

</execution> </executions> </plugin> </plugins> </build> </profile>

Les prols sont ainsi un mcanisme puissant que propose Maven pour offrir plusieurs visages un projet, sans perdre le bnce dune conguration unique pour tous. En activant les prols 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 prol avec loption -P. Il ne signie pas que ce prol est toujours actif. Cela peut donc avoir des effets indsirables si on introduit un nouveau prol sur un projet, car ceux qui taient jusquici "actifs par dfaut" seront alors dsactivs.

Tester laccs une base de donnes


Notre application utilise galement comme une trs grande majorit des applications dentreprise une base de donnes. Une nouvelle fois, nous ne voulons pas que cette partie technique de notre code passe au travers de loutillage de test ; aussi, crivons-nous des tests unitaires qui passent les requtes SQL pour sassurer de leur traitement correct dans notre code. Nous utilisons des outils ddis ces tests un peu particuliers pour nous faciliter la tche, comme DBUnit ou Unitils (si vous ne les connaissez pas, il est encore temps de rattraper votre retard !). La difcult que ces outils viennent traiter est linitialisation de donnes de test prvisibles, de manire quun test qui repose sur le compte utilisateur "Marcel Dupont" trouve effectivement ce compte en base dans ltat prvu. Voil qui colle parfaitement avec nos attentes : une construction reproductible tout moment, via des donnes de test totalement prvisibles. Herv met en place les plugins Maven qui peuvent nous aider dans cette tche. Le Listing 5.4 prsente la conguration du plugin SQL servant recrer compltement la base de donnes et effacer les traces dune excution prcdente ou de modications manuelles qui pourraient impacter le bon droulement et la reproductibilit de nos tests. Dautres scripts injectent des donnes de tests communes avant lexcution de ceux-ci. Cette conguration, bien quun peu longue (davance, veuillez excuser la verbosit du

80

Premiers pas avec Maven

Partie I

XML utilis par Maven), dnit 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 enn linjection de donnes de test de rfrence. Il existe galement un plugin pour DBUnit qui permet dutiliser le format spcique 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

Mettre en place des tests dintgration

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 conguration 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 congure une base de donnes Oracle ou MySQL sur votre poste durant la construction du projet. Nous devons donc faire conance au dveloppeur et penser quil dispose sur son environnement dune base de donnes fonctionnelle et correctement congure 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 enn coller aux attentes du projet. Demander chaque dveloppeur de disposer dune base de donnes, de chiers de test ou de simulateurs fonctionnels, alors quil nintervient que sur une sous-partie du logiciel est contre-productif. Ici aussi, un prol ddi simpose ! Avant de voir les dveloppeurs web se plaindre de devoir installer Oracle Express juste pour les tests, Herv dnit un nouveau prol db ddi cette partie spcique 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

Premiers pas avec Maven

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.

Utiliser des tests fonctionnels


Jusquici, nos tests se sont limits une approche unitaire, dans laquelle nous validons le fonctionnement de composants isols, ventuellement implants dans leur environnement technique, mais gure plus. Une autre faon, complmentaire, de tester une application est de faire appel des outils de test fonctionnels, lesquels visent dcrire les cas de test de manire aussi conviviale et "non informatique" que possible. Ces tests sont donc lisibles pour un utilisateur nal et facilement ditables pour coller au mieux aux besoins. Nous utilisons Fitnesse1 pour dnir nos tests fonctionnels. Cet outil se prsente lutilisateur comme un wiki, ditable en ligne via une syntaxe simple ; un outil particulirement convivial qui sadresse un public rebut par les langages de programmation. La Figure 5.2 montre lun de nos tests Fitnesse. Ses intentions sont comprhensibles par tous, loin de la syntaxe obscure dun bout de code jUnit.

Figure 5.2 Un test fonctionnel crit sous Fitnesse.

1. http://www.tnesse.org.

Chapitre 5

Mettre en place des tests dintgration

83

Le Listing 5.5 prsente la conguration du plugin Maven2 permettant dexcuter nos tests Fitnesse lors de la construction du projet.
Listing 5.5 : Configuration du plugin Fitnesse
<plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>fitnesse-maven-plugin</artifactId> <version>1.0-beta-2</version> <configuration> <fitnesses> <fitnesse> <hostName>myFitnesseServer</hostName> <port>80</port> <pageName>mySuitePage</pageName> </fitnesse> </fitnesses> <failOnError>true</failOnError> <classPathProvider>maven</classPathProvider> </configuration> </plugin>

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 suft 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 qualier 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 reter la couverture technique mais pas ladquation du code avec la demande.
2. http://mojo.codehaus.org/tnesse-maven-plugin.

84

Premiers pas avec Maven

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.

Tester la charge et les performances


Tous les tests qui prcdent ont un point commun : ils sont mono-utilisateurs. Ils valident le fonctionnement de lapplication mais pas sa capacit traiter la charge dutilisateurs simultans et viter les interblocages et autres crasements qui peuvent en rsulter. Comme tous nos tests, des tests de charge de ce type sont intressants un instant t mais ils le sont beaucoup plus si on est en mesure de les rejouer lidentique et danalyser lvolution des rsultats. Et, bien sr, ils deviennent rapidement indispensables si nous sommes en mesure dautomatiser le processus et dagrger les rsultats dans un outil de suivi. Quel chef de projet ne rve pas dun tableau de bord lui indiquant, via une courbe synthtique lvolution de la capacit de son application semaine aprs semaine, encaisser une charge de 100, 200 et 500 utilisateurs simultans ? Nous faisons appel jMeter3, outil de la fondation Apache, pour dnir des scnarios de test. Cet outil permet denregistrer puis de rejouer volont des scnarios pour charger une application web, un service web SOAP, une base de donnes JDBC, un serveur de messagerie JMS, ou encore un annuaire LDAP Il sutilise la plupart du temps en deux temps : 1. On se place au cours dune premire phase dans un mode denregistrement, pour lequel jMeter va agir en mandataire pour accder notre application et enregistrer toutes nos actions. Le rsultat est un scnario dutilisation de notre application que nous pouvons par la suite modier ou instrumenter pour le rendre plus intelligent quune simple rexcution lidentique. 2. Le mode charge permet de rejouer notre scnario depuis plusieurs threads selon un ordonnancement notre convenance. Il est ainsi possible de tester le comportement de notre application web sous 100 requtes par seconde avec juste ce quil faut de dlais alatoires pour simuler une charge raliste.
3. http://jakarta.apache.org/jmeter.

Chapitre 5

Mettre en place des tests dintgration

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 suft 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 chiers 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 conguration minimale, il ne nous reste plus qu invoquer la commande mvn jmeter:jmeter pour envoyer notre application les 50 requtes par seconde qui vont vrier 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, congurer 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

Premiers pas avec Maven

Partie I

Avec tous nos nouveaux prols, comment congurer 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 identier la moindre de nos modications, est congur 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 identi tardivement sur un projet, surtout si cest pour constater au nal 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 nalement eu plus que prvu. Tout cela alors quon dispose de tout loutillage ncessaire pour identier 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 ds 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 prols 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 efcacement une application est une tche tellement

Chapitre 5

Mettre en place des tests dintgration

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 conguration Maven et gagnera en homognit. Placez vos scripts de test sous SVN et voyez comment congurer 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

xmlUnit dbUnit httpUnit ..*Unit Spcialisation technologique

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 uctuations 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 dnir 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 ctif" 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 ldice. 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.

Oracle, quand tu nous tiens


La construction du projet choue dans sa toute premire phase. Voil qui nest pas trs encourageant ! Maven signale le problme de dpendance indiqu au Listing 6.1.
Listing 6.1 : Erreur de rsolution des dpendances
[ERROR] BUILD ERROR [INFO] -----------------------------------------------------------------------[INFO] Failed to resolve artifact. Missing: ---------1) com.oracle:ojdbc14:jar:10.2.0.2.0 Try downloading the file manually from the project website. Then, install it using the command: mvn install:install-file -DgroupId=com.oracle -DartifactId=ojdbc14 -Dversi on=10.2.0.2.0 -Dpackaging=jar -Dfile=/path/to/file

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

=10.2.0.2.0 -Dpackaging=jar -Dfile=/path/to/file -Durl=[url] -DrepositoryId=[id]

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),

Un moteur de recherche pour Maven Notre dclaration de dpendance est-elle incorrecte ? Peut-tre nutilisons-nous pas le bon identiant de groupe en spciant com.oracle, alors quil faudrait indiquer com.oracle.jdbc, com.oracle.driver ou encore oracle tout court ? Nous pouvons, bien sr, nous lancer dans une recherche manuelle mais cela risque rapidement dtre pnible et pas forcment trs concluant. Dautres ont eu ce mme problme et ont donc mis en place des moteurs de recherche spcialiss pour Maven, par exemple, le site mvnrepository.com qui offre une indexation du dpt central utilis par dfaut par Maven. Nous y faisons une recherche sur le mot "oracle", et nous obtenons rapidement la conrmation attendue sur lidentit de notre pilote JDBC (voir Figure 6.1). Nous voil au moins rassurs pour lidentication de notre dpendance : nous avons spci les groupe, artifactId et version corrects. Mais alors, pourquoi Maven ne parvient-il pas tlcharger ce pilote JDBC ? La rponse est relativement vidente si vous vous connectez au site Oracle : la distribution de cette bibliothque est soumise laccord dOracle, et elle ne peut tre tlcharge quaprs enregistrement sur le site de lditeur. Lquipe Maven qui gre le dpt ne peut donc pas la mettre librement disposition de chacun, tout juste peut-elle proposer un chier POM et un groupe clairement dni pour ce pilote. Il revient donc chacun daller tlcharger manuellement le chier indiqu.

Chapitre 6

Gestion avance des dpendances

93

Figure 6.1 Recherche dun artefact via un moteur de recherche spcialis.

Pourquoi publier un POM sans JAR ? Quel intrt y a-t-il publier sur central le POM du pilote Oracle si la bibliothque ne laccompagne pas ? Un lment de rponse gure dans le paragraphe qui prcde : toute personne utilisant Maven qui recherche ce pilote va au moins utiliser des identiants de groupe, dartefact et les versions dj rfrences. Cela assure lhomognit des projets. Ensuite, le chier POM compte de nombreuses mtadonnes qui peuvent informer sur la bibliothque, en particulier :
m m m

Lorganisation qui dveloppe cette bibliothque. Une description qui peut nous aider conrmer son identit. 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). LURL o on peut la tlcharger. Tout site Internet respectueux de ses utilisateurs ne changerait jamais une URL de tlchargement, nest-ce pas ?

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 modication 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 able lanalyse des licences sur un projet. Ce serait cependant une fonctionnalit trs intressante de Maven.

Installer le chier manquant Grce aux informations du POM, nous sommes enn en mesure de rcuprer la bibliothque du pilote JDBC Oracle en suivant la procdure lgale de tlchargement, aprs avoir lu en dtail la longue page dacceptation de la licence. La solution que propose spontanment Maven, cest dinstaller la bibliothque manquante la main. La commande utiliser a t fournie dans le message du Listing 6.1. Il nous suft de faire un copier-coller dans notre console en indiquant le chier en question ce qui suppose tout de mme que nous layons trouv quelque part et, bien sr, que nous soyons parfaitement certains de lidentit du chier. Le numro de version 5 chiffres utilis par Oracle nest pas trs rassurant de ce point de vue. Il y a de toute vidence de nombreuses micro-versions, sans doute des correctifs successifs dont nous navons pas strictement besoin, mais qui sait ? Cest une solution rapide, tout fait lgitime si nous disposons de la bibliothque en question par un autre moyen. Les dpendances "System" Nous avons donc une solution pour le pilote Oracle ; cependant, chacun de nous doit linstaller dans son dpt local. Mme si nous nous le passons par mail, cl USB ou partage de rpertoire interpos (ce qui sous-entend que nous navons pas trs bien lu la longue page de licence du site Oracle), ce nest pas trs pratique. Dun point de vue lgal, chaque dveloppeur doit accepter individuellement la licence Oracle pour obtenir le fameux pilote. Une faon courante de lobtenir est donc de tlcharger et dinstaller lenvironnement de dveloppement Oracle (client natif et autres

Chapitre 6

Gestion avance des dpendances

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 gure 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 chier 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 chier 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 chiers 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

Crer son propre dpt


Carlos napprcie pas de nous voir changer des JAR par cl USB juste pour obtenir notre fameux pilote JDBC. Il aime la gestion transparente et totalement automatise des dpendances par Maven, aussi dcide-t-il de mettre en place notre propre dpt priv pour venir complter ce qui pourrait manquer sur le dpt central de Maven. En combinant les deux, nous ne devrions plus tre gns par ces histoires de JAR manquant. Cette solution est la plus couramment retenue et galement la plus souple. Crer son propre dpt priv pour les bibliothques dont la diffusion nest pas libre ou pour hberger ses propres dveloppements destination dautres projets internes permet de grer de manire centralise et dnitive ces problmes de dpendances rcalcitrantes. Physiquement parlant, un dpt nest rien de plus quun systme de chiers accessible depuis les postes de dveloppement soit directement (protocole file:), soit via un serveur HTTP. Il nest donc pas bien compliqu de faire hberger sur votre serveur intranet un sous-domaine http://repository.masociete.com. Pour mettre disposition notre driver Oracle, il nous suft donc de crer larborescence adquate et dy placer le JAR sous le nom appropri. Il reste alors indiquer Maven lemplacement de notre dpt "maison", ce qui se traduit par un lment <repository> dans le POM :
<repositories> <repository> <id>private</id> <url>http://repository.noubliepaslalistedescourses.fr</url> </repository> </repositories>

ASTUCE Plutt que de regrouper nos dclarations de dpts dans la conguration, nous pouvons les placer dans le chier settings.xml utilis pour congurer Maven. Le gestionnaire de dpt Nexus peut mme gnrer ce chier avec les dclarations adquates.

Contrle didentit, vos papiers sil vous plat ! Le dpt de bibliothques ne contient pas seulement le chier POM de notre pilote JDBC, mais aussi deux chiers sufxs md5 et sha1 associs larchive JAR. Il sagit des sommes de contrle de larchive qui, elle, nest pas disponible dans le dpt.

Chapitre 6

Gestion avance des dpendances

97

Ces sommes de contrle sont lquivalent de nos empreintes digitales. Un bit modi 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 chier 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 enn 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 l 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

Une lecture approfondie de la documentation, et plus particulirement de la Sun Binary Code License, rpond cette question. Comme de nombreuses API, JMS en version 1.0.2 a t diffus par SUN sous une licence contraignante, interdisant la libre distribution de larchive Java. Il est donc lgalement interdit de mettre ce chier disposition dautres utilisateurs, et en particulier central, le dpt ofciel de Maven, doit se plier au respect de cette rgle. La licence SBCL impose en fait chaque utilisateur de cocher la petite case "Jaccepte la licence dutilisation" avant de pouvoir obtenir larchive Java tant convoite. Ce petit rafnement qui parat anodin est un obstacle incontournable au tlchargement automatis des bibliothques.
Pourquoi Maven ne propose-t-il pas daccepter la licence ? Au mme titre que le site de tlchargement de SUN, Maven pourrait techniquement parlant proposer daccepter la licence avant deffectuer le tlchargement. Cela serait satisfaisant sur le plan lgal et viterait ce genre daberration pour les utilisateurs. Lquipe du projet Maven na cependant pas suivi cette option. Dune part, cela introduit une interaction avec lutilisateur qui nest pas compatible avec le mode de fonctionnement "batch" prvu par Maven (qui peut aussi sexcuter sur des machines automatises). Dautre part, lquipe tant trs attache aux valeurs du logiciel libre, elle a fait front pour faire voluer lapproche de SUN pour ses licences, au point que Java 7 est aujourdhui totalement libre ! Une belle victoire, qui nous permet de tlcharger librement la bibliothque JMS 1.1 depuis le dpt central. SUN na cependant pas pouss la courtoisie jusqu changer la licence de ses anciennes bibliothques, do notre problme avec JMS 1.0.2.

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 inuence 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.

Grer son dpt priv


Ce qui devait au dpart tre une tche de fond pour Carlos se rvle rapidement un casse-tte. Dans un premier temps, Carlos a voulu faire plaisir tout le monde cest un peu une deuxime nature chez lui et a donc rpondu favorablement toutes nos demandes :

Chapitre 6

Gestion avance des dpendances

99

Fabrice : jai besoin de trucUtils, peux-tu lajouter ? Carlos : pas de soucis. Do a vient, quelle version ? Fabrice : je lai trouv sur sourceforge, et a doit tre la version 1.2 Carlos : OK, cest en place. Tout aurait pu se passer dans cette bonne humeur gnrale jusqu ce que, dune part, Carlos croule sous les demandes, mais surtout que les choses se compliquent sensiblement :

Olivier : Salut Carlos, jaurais besoin de trucUtils. Carlos : pas de soucis, ds que jai deux minutes. Do a vient, quelle version ? Olivier : de trucUtils.org, et cest la version 1.2 Carlos : Attends, a me dit quelque chose a serait pas le mme que net.sourceforge:trucUtils ? Olivier : hum non, celui-l ne fait que 18 Ko, a devait tre la version bta. La version nale fait 21 Ko. Carlos : OK. a tennuie si je le renomme "1.2-nal" dans le groupe net.sourceforge ? Olivier : ben cest un peu bte, toute leur doc est sur trucUtils.org ! Je vous laisse imaginer la suite de la journe de Carlos. Rapidement, notre dpt "maison" compte des doublons, des erreurs de mtadonnes ou des versions farfelues pour compenser les erreurs prcdentes.
Maven1 ou Maven2 ? De nombreux dpts de bibliothque Maven existent en version "Maven1" ou "Maven2". Le premier format est conserv pour des raisons historiques. Le second prsente une structure plus hirarchise et des mtadonnes supplmentaires. Maven2 sait utiliser les deux formats. Le dpt central, qui pointe physiquement sur les mmes chiers, est accessible au format Maven12.

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 n dun numro de version indique quil sagit dun artefact en cours de dveloppement, sujet modications. 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 modications 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 modie du plugin. Pour que celle-ci soit utilise, nous devons mettre jour le chier de mtadonnes associ, sans quoi Maven ne verra rien de nouveau et ne la prendra pas. Carlos doit donc manuellement fusionner le chier de mtadonnes quil a obtenu du dpt ofciel 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.

Passer un "vritable" gestionnaire de dpt


Carlos perd un temps fou dans la gestion de son dpt priv car les "utilisateurs" nont pas de moyen simple pour rechercher une bibliothque. Il manque aussi des outils pour vrier le contenu du dpt : les sommes de contrle sont-elles prsentes et correctes ? Les chiers POM sont-ils valides ? Enn, et cest loin dtre ngligeable, nous dpendons dune connexion Internet pour tout ce qui nest pas dans notre dpt priv. Une coupure rseau et cest limpasse assure pour ceux qui nont pas dj tlcharg toutes les dpendances ncessaires. Il est temps de passer la vitesse suprieure et de faire appel un outil ddi pour la gestion de notre dpt priv. Maven utilise un chier de conguration local, plac sous $HOME/.m2/settings.xml. Ce chier XML (un de plus !) permet de dclarer un miroir qui va remplacer les accs

Chapitre 6

Gestion avance des dpendances

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 able 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 cone 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 m m

recherche parmi les artefacts prsents dans le dpt ; identication dun JAR par recherche de son empreinte MD5 ; miroir dun autre dpt, typiquement pour conserver un cache local de central et/ou dautres dpts ; conversion la vole dun dpt Maven 1 au format Maven 2 ; indexation des dpts et publication dun index uni ; tlchargement (upload) de nouveaux artefacts, lquivalent de la commande mvn install-le ; interface graphique dadministration plus ou moins sexy selon loutil considr ; contrle daccs pratique pour autoriser un utilisateur grer certaines parties du dpt sans prendre le risque de tout casser ; mcanismes daudit, dindexation et de contrle dintgrit en tche de fond.

m m m

m m

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 congurs 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 inme partie des gigaoctets de bibliothques.

Chapitre 6

Gestion avance des dpendances

103

En fonction des besoins des projets, Carlos va rapidement ajouter dautres dpts la conguration : 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 chier settings.xml chaque nouvel arrivant dans la conguration 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 chier 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 dnissez 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. Enn, 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 Conguration 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 identis, 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 dnie par une bibliothque ou servir identier 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). Enn, un espace de stockage permet la diffusion des dveloppements au reste de lquipe, servant de dpt "publicpriv".

Chapitre 6

Gestion avance des dpendances

105

Figure 6.3 Rapports daudit dArchiva.

Figure 6.4 Page de recherche dArtifactory.

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 able 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 congur 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. Enn, 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 dauthentication 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 afrmation nest pas tout fait exacte et nous lavons dj vu au Chapitre 4 : la notion de classier 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.

Nous avons dj t confronts ce problme lorsque Franois a propos une version Flex de notre interface web (voir le Chapitre 3). La construction dun binaire SWF tait tout fait possible, mais ncessitait un projet et un POM ddi. Pour linstant, nous

108

Maven en entreprise

Partie II

avons fait avec cette contrainte en crant autant de chiers 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 conguration Maven entre les diffrents POM. Les mmes plugins, les mmes paramtres, les mmes versions de dpendances sont multiplis dans chacun de ces chiers sans mutualisation. Face au formalisme XML du chier POM, notre premier rexe 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 chier 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 chier 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 dnis par son parent, sauf sil les rednit 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 identi 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

Quand le projet devient trop lourd

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.

Packaging dun POM parent Notre POM parent est donc lui-mme un autre projet Maven, mais celui-ci ne va pas produire de JAR, de War ou mme de binaire excutable. Il va se contenter du seul chier POM qui permet de mutualiser notre conguration. Le packaging pom est prvu cet effet. La construction dun projet de ce type utilise un cycle de vie simpli qui se limite publier le chier POM dans le dpt. Le Listing 7.1 montre le POM parent sur le projet noubliepaslalistedescourses. Il nous permet de congurer en un seul endroit lutilisation de Java 5 comme cible de compilation.
Listing 7.1 : pom parent du projet
<project> <modelVersion>4.0.0</modelVersion> <groupId>fr.noubliepaslalistedescourses</groupId> <artifactId>noubliepaslalistedescourses-parent</artifactId> <version>1.0.0</version> <!-- configuration commune --> <build> <plugins> < !-- ... TODO --> </plugins> </build> </project>

La conguration 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 spciant un super-parent qui dnira une conguration Maven propre notre organisation et applicable tous ces projets. On y trouvera, par exemple, la conguration 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 dnissent 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 Configuration commune tous les projet de la fondation apache Configuration commune tous les modules du projet Maven

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 simplie 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 modication avant de pouvoir constater ses effets sur les projets qui en hritent. Maven a heureusement prvu le coup : en plus de lidentication 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 efcace si vous utilisez un gestionnaire de version du code comme Subversion. Celui-ci permet, en effet, de dnir 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

Quand le projet devient trop lourd

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 conguration, 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 spcique. Cela allge la conguration 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 chier 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 dnir les versions par dfaut de ces dpendances. Notre chier POM parent va ainsi lister quelle version de chaque bibliothque fait ofce 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 difcile 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>

Cette version "pirate" de commons-logging est disponible dans le repository Maven de JBoss. Lutilisation du scope provided nous permet dtre srs quelle ne sera pas ajoute dans nos livrables de type WAR.

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 bncier dune fonction particulire. De la mme faon, si les rgles de lentreprise limposent, un corporate POM peut dnir les versions valides et supportes des bibliothques, que chaque projet pourra alors utiliser en toute conance. 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 dnissant 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

Quand le projet devient trop lourd

113

deux versions dun mme plugin, lutilisation de versions incohrentes est source de bizarreries, voire de bogues trs dlicats identier. 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 chier POM nimpose pas de dclarer pour chaque plugin utilis un numro de version. Il est cependant fortement recommand de xer 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 l 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 chiers 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 let. 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 vrier certaines rgles. Lune des rgles prdnies exige justement de vrier que chaque plugin du projet a une version correctement dnie.
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 chier POM en tant que document XML, ce qui serait peu utile puisque la version du plugin peut tre dnie 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 dnie 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 spciques dnies par le projet. Il peut ainsi vrier que le dveloppeur utilise une version prcise de Maven ou du JDK, mais aussi que certains chiers 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).

Diviser pour rgner


Stphane est trs satisfait de la solution du POM parent que nous venons de dcouvrir, lui qui en avait assez de passer en revue un un nos chiers POM pour mettre en place une conguration cohrente. Il reste cependant un peu sur sa faim : pour construire toute lapplication et la tester dans son ensemble, il doit encore passer de projet en projet pour lancer rptition la commande mvn install. Les choses se compliquent mme rapidement lorsquil doit tenir compte dune dpendance entre deux sous-projets. Un projet de type POM inclut cependant une particularit que nous navons pas encore explore : il peut dnir un lment <modules>. Celui-ci dclare une liste de modules qui sont, en fait, des chemins relatifs au POM. Lorsque nous demandons Maven de construire un projet de ce type, il exploite cette information pour rechercher dans chacun de ces chemins un autre projet Maven construire, quil intgrera dans une macroconstruction de projet. En plus denchaner la construction des projets/modules,

Chapitre 7

Quand le projet devient trop lourd

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 suft 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 simplie 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 ne 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 rete 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 identier chaque module comme un projet ajouter dans la conguration de lintgration continue.

116

Maven en entreprise

Partie II

Continuum a nanmoins ici un coup davance sur la concurrence : en dtectant une modication dans le code du projet, il va lancer la construction du module concern, puis exploiter la gestion des dpendances entre projets pour lancer la construction de tous les autres modules qui en dpendent et pourraient donc tre impacts, mais pas de ceux qui nont aucun lien direct ou indirect avec la modication. Mais Hudson le talonne de prs et commence supporter lui aussi une gestion plus intelligente de Maven suivre ! Lavantage de ce fonctionnement, dtaill dans la Figure 7.2, est que la construction dun module (ou de plusieurs) est plus rapide que celle du projet dans son ensemble. Le serveur sera ainsi plus ractif : une modication errone sur un module sera identie rapidement, son impact sur un autre module apparatra en quelques instants, alors quune construction complte aurait pu prendre de longues minutes, impliquant de nombreux modules non concerns par la modication.
Projet parent

Dtection dune modification

Module base de donnes Module domaine mtier Module services mtier Module application web Module services web

Projet non impact Projet non impact

Enchane la construction

Figure 7.2 Raction du serveur dintgration continue une modication.

Un gros projet vs plein de modules Certains utilisateurs napprcient pas le dcoupage en nombreux modules quencourage Maven. Ils ont limpression que leur projet seffrite en petits bouts de code sans grande valeur et dlicats identier pour les utilisateurs naux. Cette impression dcoule dune habitude prise avant lapparition de Maven, qui consiste proposer un gros JAR avec tout ce qui est ncessaire lintrieur pour que les utilisateurs naient pas se soucier des dpendances. Paradoxalement, cette pratique est plus prilleuse quelle ny parat et introduit des incompatibilits sans solution lorsquon veut marier deux outils construits avec cette optique.

Chapitre 7

Quand le projet devient trop lourd

117

Les utilisateurs de Maven nont plus se proccuper des problmes de dpendances, et chaque module peut prciser nement ce qui lui est ncessaire. Au contraire, un artefact unique devra :
m

soit dclarer trop de dpendances, dont un grand nombre ne sont ncessaires qu des fonctions que certains utilisateurs considreront comme annexes alors quelles sont indispensables pour dautres ; 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 n 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 magnique 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 signicative 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.

Java Entreprise Edition


Le modle JEE na pas trs bonne rputation. Il dnit (entre autres) deux rles spcialiss : le dveloppeur et lassembleur de composants. Ce dernier est charg de dnir, via des descripteurs de dploiement, la faon dont des macrocomposants sont lis au sein dune application dentreprise. Ces macrocomposants, ce sont les EJB, connecteurs et applications web que nous devons regrouper dans une archive dentreprise EAR. Les descripteurs, ce sont ces (trop ?) nombreux chiers XML dans lesquels nous dclarons des rfrences vers dautres composants ou vers des ressources du serveur (typiquement, une base de donnes). Nous y enregistrons aussi lidentit de chaque composant pour sa parution dans un annuaire JNDI. La Figure 8.1 rsume cette structure.

120

Maven en entreprise

Partie II

Si vous ntes pas familier avec la norme JEE ou si vous voulez en avoir une description plus ne et moins biaise que notre rsum de quelques lignes, nous vous recommandons lintroduction disponible sur le site de SUN1.

Archive dentreprise (EAR) Entreprise Java Bean (EJB) Descripteur de dploiement Application web (WAR) Descripteur de dploiement Descripteur de dploiement

Annuaire JNDI

liaison

Source de donnes Serveur dapplication JEE

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 chier binaire, un WAR nest rien dautre quune archive JAR avec une extension spcique, donc rien de bien compliqu. Nous devons cependant suivre la structure dnie par la norme JEE, en particulier le rpertoire WEB-INF qui doit contenir :
m m

le descripteur de dploiement web.xml ; un sous-rpertoire classes avec le code compil de nos servlets et des autres classes ncessaires notre application ; un sous-rpertoire lib avec les bibliothques utilises.

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 conguration 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 an 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 WEB-INF/classes


...LoginServlet.class

Chargeur de classes de lapplication web WEB-INF/classes


...LoginServlet.class

WEB-INF/Lib *.jar LoginServlet implements Servlet

WEB-INF/Lib
Servlet-api-2.5.Jar

LoginServlet implements Servlet ClassCastException

Chargeur de classes du serveur dapplication Commons/lib *.jar

Chargeur de classes du serveur dapplication Commons/lib *.jar


Servlet-api.jar

Servlet

Servlet-api.Jar

Figure 8.2 Comparaison de la structure des chargeurs de classes : thorie vs pratique.

En jetant un coup dil notre WEB-INF/lib, nous y dcouvrons le coupable : servlet-api-2.5.jar. Un servlet cr dans notre application web aura comme type parent une classe qui est charge elle aussi par lapplication web, et pas le javax.servlet.Servlet commun tout le serveur dapplication. Do cet trange message derreur. Vincent est rassur sur sa sant mentale.
INFO Lorsquil sagit du JAR de lAPI servlet le constat est rapide, mais il peut arriver quune bibliothque ait la mauvaise ide de contenir les classes dune API Java (plutt que den dpendre), comme par exemple le JAR gwt-user de GWT. Lidentication du coupable est alors nettement moins immdiate.

Cette dpendance javax.servlet:servlet-api:2.5 est pourtant indispensable notre application pour quelle soit en mesure de compiler. Nous faisons de nombreuses rfrences directes ces classes dans notre code ! Nous avons dj explor les scopes que nous pouvons affecter nos dpendances. Le scope par dfaut ( compile) signie que la bibliothque associe est ncessaire pour compiler et sexcuter, cest donc a priori

Chapitre 8

Maven et JEE

123

bien le cas. Il existe cependant un autre scope, provided, qui est trs proche avec une nuance signicative : il dclare une dpendance ncessaire pour compiler et sexcuter mais qui est fournie par lenvironnement dexcution, typiquement notre serveur JEE. La modication suivante sur nos dpendances corrige donc ce problme assez dboussolant et nous permet enn 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 prot 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 nit par nous faire penser que Vincent a dcidment le nez n : <packaging>ejb</packaging> dans le POM suft pour changer la conguration par dfaut du cycle de vie et produire un EJB. La seule chose que nous devrons y ajouter est la conguration 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 dnit 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 conguration <generateClient>true</generateClient>. Nous obtenons donc au nal deux archives Java :
m m

noubliepaslalistedescourses-ejb-1.0.0-SNAPSHOT.jar, notre fameux EJB ; noubliepaslalistedescourses-ejb-1.0.0-SNAPSHOT-client.jar, larchive des classes client qui permettra dinvoquer notre EJB.

Dans notre application web, il nous suft 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 sidentier 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

125

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>

Listing 8.2 : Descripteur de dploiement de notre application web


<?xml version="1.0" encoding="UTF-8"?> <web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"> < !-- Servlet GWT-RPC de l'application web --> <servlet> <servlet-name>gwt-rpc</servlet-name> <servlet-class> org.springframework.web.servlet.DispatcherServlet </servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>gwt-rpc</servlet-name> <url-pattern>*.rpc</url-pattern> </servlet-mapping> < !Rfrence vers notre EJB --> <ejb-ref> <ejb-ref-name>ejb/ListeDeCourses</ejb-ref-name> <ejb-ref-type>Session</ejb-ref-type> <ejb-ref-home> fr.noubliepaslalistedescourses.ListeDeCoursesHome </ejb-ref-home> <ejb-ref-remote> fr.noubliepaslalistedescourses.ListeDeCoursesRemote </ejb-ref-remote> </ejb-ref> </web-app>

126

Maven en entreprise

Partie II

Construire une archive dentreprise EAR Il ne nous reste plus qu prendre nos composants et les grouper dans un joli paquetcadeau avant de lenvoyer notre hbergeur. En terme JEE le paquet-cadeau est une archive dentreprise EAR. Pour produire ce nouvel artefact, Vincent applique la recette qui lui a jusquici russi et fait mouche une nouvelle fois : un nouveau module, avec comme packaging ear suft pour produire un artefact EAR. Si tout pouvait tre aussi simple enn, passons. La seule chose dclarer dans le POM de ce nouveau module est la liste de dpendances, pointant vers nos composants JEE, inclure dans lEAR dans notre cas, lapplication web et lEJB, mais potentiellement plusieurs composants de ce type et/ou des connecteurs RAR ou autres subtilits JEE propritaires ou non. Le plugin ear compte de nombreuses options qui permettent dajuster nement le nom de chaque composant lintrieur de larchive EAR. Il propose mme de gnrer pour nous le descripteur de dploiement application.xml, ce qui nous fera toujours un chier de moins maintenir. Nous avons un bel EAR prt pour une mise en production, cependant un dtail chagrine Vincent : notre application web, comme notre EJB, utilise plusieurs bibliothques utilitaires, telles que commons-lang ou commons-io. Dans sa structure actuelle, nous retrouvons ces chiers en double, une fois dans le WEB-INF/lib de lapplication web, une fois dans le chier EJB. Ce nest pas intellectuellement trs satisfaisant. Le modle JEE a prvu le dcoupage des composants en modules mais na pas non plus nglig la mutualisation des bibliothques. Le mtachier MANIFEST permet de dclarer des bibliothques ncessaires lexcution dun module JEE, bibliothques qui seront alors mises disposition via lEAR. Maven na pas non plus nglig cet aspect du packaging JEE, et nous devons revenir dans notre projet application web pour marquer les dpendances que nous voulons prsent exclure de WEB-INF/lib pour les mutualiser. la premire tape, on demande au plugin war de construire, dans les mtadonnes de larchive, lindication de classpath :
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-war-plugin</artifactId> <version>2.0.2</version> <configuration> <archive> <manifest> <addClasspath>true</addClasspath> </manifest> </archive> </configuration> </plugin>

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 suft 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 spciquement web quil emploie. La Figure 8.3 indique la structure nale 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>

WAR MANIFEST.MF Classpath: ...

POM EAR

EAR commons-io.jar

Figure 8.3 Multiprojet JEE avec mise en commun des dpendances via lEAR.

128

Maven en entreprise

Partie II

Tester
Nous savons dsormais construire notre archive dentreprise en une seule ligne de commande, respectant la lettre la spcication 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 dnition, 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 modication 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 ns de test rien que a. Il se compose de deux parties :
m

Un enregistreur, qui se base sur le navigateur Firefox et permet de capturer une squence dactions sur ce dernier. Vous enregistrez ainsi un scnario dutilisation type de votre application. 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

Dmarrer la partie serveur (le contrleur) de Selenium. Elle va permettre de faire le lien entre le test et le navigateur. Lancer le navigateur disponible sur la plateforme. Excuter le test sur le navigateur sous le contrle du serveur. 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). Fermer le navigateur et arrter le serveur pour librer correctement les ressources de la machine hte.

m m m

130

Maven en entreprise

Partie II

Le plugin selenium vient notre secours : il propose deux tches complmentaires, charges de faire dmarrer et darrter proprement le contrleur Selenium, respectivement au cours des phases pre-integration-test et post-integration-test. Ce qui nous laisse donc la phase integration-test pour excuter nos tests, comme a tombe bien ! Nous lavons vu, Selenium peut stocker les scnarios sous forme de chiers HTML. Le plugin selenium propose une tche ddie ce format qui permet de les excuter au cours du build Maven. Il est donc facile doutiller une application de tests de nonrgression : il suft denregistrer des scnarios au format HTML et dajouter la conguration du Listing 8.4 ; les tests seront alors rejous lidentique chaque construction complte du projet.
Listing 8.4 : Configuration du plugin Selenium
<plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>selenium-maven-plugin</artifactId> <version>1.0-rc-1</version> <executions> <execution> <phase>integration-test</phase> <goals> <goal>selenese</goal> </goals> </execution> </executions> <configuration> <browser>*firefox</browser> <startURL>localhost:8080/myApp</startURL> <suite>src/test/selenium/suite.html</suite> </configuration> </plugin>

La seconde option, fonde sur lenregistrement et lenrichissement ventuel de nos scnarii de test au format jUnit, va utiliser le plugin standard surefire pour lexcution des tests. Il sera simplement congur de manire spcique pour sexcuter lors de la phase integration-test. Magique ! Vincent sempresse dajouter notre projet le plugin surefire qui prend en charge lexcution de tests jUnit et de lassocier cette phase de test dintgration. Sitt dit, sitt fait, mais l gros problme : nos tests sont excuts avant que le contrleur Selenium ne dmarre. Nous lavions oubli, mais Surere est dj congur pour sexcuter au cours de la construction de notre projet,

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 congurer Surere avec des patrons complmentaires dinclusion/exclusion pour que chaque test se droule dans la phase adquate. Le Listing 8.5 montre la conguration dans le chier POM qui met en uvre cette stratgie. Les tests Selenium sont sufxs 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 conguration est alors plus simple, et nous disposons dun emplacement ddi pour la dnition 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 prdni. 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 nafchera 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 conguration, 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 congurer 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 conguration est un peu moins facile que pour un plugin plus "simple" (voir Listing 8.6). Cet extrait de notre POM dnit les paramtres dutilisation de Cargo :
m

Lexcution lors des phases pre-integration-test et post-integration-test pour installer, congurer et dmarrer puis arrter proprement le serveur. Lidentication du serveur utilis, via la cl jboss42x, et des rpertoires de travail, de log ainsi que de lemplacement depuis lequel larchive sera tlcharge. La conguration du serveur et de la machine virtuelle Java qui va lexcuter. 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 chier XML, dans un format spcique de JBoss, qui nous permet de dnir laccs notre base de donnes de test.

m m

Listing 8.6 : Configuration du plugin Cargo


<plugin> <!-Dmarrage d'un serveur JBoss 4.0.2 et dploiement de l'appli web @see http://cargo.codehaus.org/Starting+and+stopping+a+container --> <groupId>org.codehaus.cargo</groupId> <artifactId>cargo-maven2-plugin</artifactId> <version>1.0</version> <executions> <!-- dmarrage et arrt du serveur lors d'un mvn:install --> <execution> <id>start-container</id> <phase>pre-integration-test</phase> <goals>

3. http://cargo.codehaus.org/.

Chapitre 8

Maven et JEE

133

<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>

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>

Aprs avoir ingurgit la hirarchie un peu lourde de cette conguration XML, Vincent lance la commande magique mvn install et constate avec plaisir le tlchargement puis le dmarrage dun serveur JBoss sur son environnement, et le dploiement de notre application, prte pour les tests Selenium qui ont enn du grain moudre.

Soyons pragmatiques, soyons productifs


Nous sommes donc devenus des cadors de JEE, avec une automatisation complte du processus dassemblage et de test. Sur le poste de dveloppement, les choses ne sont pas aussi roses. Pour tester une modication si mineure soit-elle sur une simple page JSP, nous devons relancer une phase lourde dassemblage et de dploiement. Lattente est longue, les nerfs en subissent les consquences et la productivit scroule. Ce nest pas faute seulement du modle JEE. Sil impose une structure dassemblage complexe qui alourdit notre processus, cest nous de trouver des outils qui proposent des raccourcis pour plus de productivit. Respecter la norme JEE pour un serveur ne signie pas se limiter la norme JEE ! Une application web "sur place" Premier constat, pour tester notre modication de JSP, notre serveur Tomcat va dcompresser notre archive WAR, retrouvant ainsi exactement la structure que le plugin war a construite dans notre rpertoire de construction (target). Le mcanisme de conguration de Tomcat permet de pointer directement sur ce rpertoire, plutt que de passer par une archive WAR. Nous pouvons mme faire mieux : pourquoi recopier notre JSP chaque modication dans le rpertoire de construction alors que la structure de lapplication web existe quasiment sous src/main/webapp ? La seule chose qui manque pour avoir une application web conforme JEE, ce sont les rpertoires WEB-INF/classes et WEB-INF/lib. Sous rserve dune conguration correcte de notre gestionnaire de code source pour ignorer

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 modication dans une page JSP sera alors applique immdiatement, via le mcanisme de recompilation des JSP qui est intgr tout serveur JEE.

Une application web sans assemblage Nous faisons de nets progrs, mais nous devons encore invoquer une commande Maven chaque dition dune classe de lapplication ou relancer le serveur lorsquun chier de conguration est modi. Le conteneur de servlets (comme Tomcat, ce nest pas un serveur JEE complet) Jetty propose un mode de fonctionnement particulirement adapt notre utilisation. Grce un plugin ddi, il se lance sur un projet Maven sans ncessiter la moindre phase de prparation. Il rfrence directement les bibliothques de notre dpt local, pointe sur notre rpertoire de compilation (target/classes) et dmarre lapplication web en un temps record avec la seule commande mvn jetty:run. Jetty va encore plus loin car il peut fonctionner en mode scrutation : il va surveiller le rpertoire de compilation et identier une modication sur une classe ou sur un chier de conguration. Il lancera alors un rechargement immdiat de lapplication. La ractivit de lenvironnement de dveloppement est alors excellente : lancement de lapplication en un minimum de temps et sans aucune prparation, prise en compte rapide des modications. Ne plus sortir de lIDE Pour ceux qui napprcient pas la ligne de commande, les IDE ont planch, de leur ct, sur le manque de productivit li au modle JEE. Eclipse Web Tools Platform se propose par exemple de redployer automatiquement lapplication lors dune modication, ce qui permet de contrler limpact dune modication sans intervention manuelle. Il suft de congurer le serveur cible pour quEclipse prenne en charge la procdure de redploiement.
INFO Web Tools Platform ne se limite pas JEE et couvre de nombreuses technologies lies au Web. Mme si vous nutilisez pas la fonctionnalit de dploiement, ce module dextension dEclipse sera rapidement indispensable pour diter convenablement les chiers HTML, JSP, XML, XSD, JavaScript, CSS, les contrats WSDL de services web et dautres formats normaliss, sans parler des petits outils bien pratiques comme lespion TCP/IP ou le client graphique de service web.

136

Maven en entreprise

Partie II

Lquipe de dveloppement de m2eclipse a eu piti des dveloppeurs et leur vite de devoir congurer chaque projet pour adapter la conguration WTP leur projet Maven. Via une extension optionnelle, m2eclipse dclarera automagiquement les modules war comme projets WTP avec les chemins et les dpendances extraites de la conguration du plugin war. Elle est pas belle la vie ? Histoire de ne pas faire comme tout le monde, Nicolas nutilise pas WTP sous Eclipse mais un petit plugin Maven in France : Sysdeo Tomcat, distribu par le site de veille technologique www.eclipsetotale.com. Ce plugin tout simple permet de lancer un serveur Tomcat, qui a lavantage dtre lger et rapide dmarrer et largement sufsant tant quon nexploite que les technologies de lAPI servlet, ce qui est le cas dune grande majorit des applications web. Ce plugin pour Eclipse a son pendant pour Maven4, lequel va congurer le plugin Eclipse en fonction du projet Maven et des multiples modules impliqus. Ce plugin Eclipse a la particularit dexploiter la souplesse de Tomcat pour pointer sur les rpertoires de compilation de chaque module prsent dans lIDE plutt que sur larchive JAR quil produit. Une modication dans un module est donc exploitable sans manipulation particulire de lIDE qui se contente de recompiler, aprs que vous avez simplement cliqu sur le bouton relancer Tomcat. Cette combinaison de deux plugins pour Eclipse et Maven apporte un support limit de JEE, mais permet de bncier dun environnement lger et raisonnablement ractif. Et pour ceux qui naiment dnitivement pas la console, Nicolas propose un petit dveloppement maison5 pour congurer Sysdeo Tomcat lors dun import de projet m2eclipse ;).
ASTUCE La seule option pour aller encore plus vite est de permettre la modication chaud des classes de lapplication web, ce qui conomise le temps de rechargement de lapplication. Le HotSwap de la machine virtuelle Java permet cette opration avec des contraintes assez fortes, mais un outil comme JavaRebel de ZeroTurnaroud permet quasiment de modier chaud tous les lments de lapplication web, y compris les chiers de conguration des frameworks courants comme Struts ou Spring.

4. http://mojo.codehaus.org/sysdeo-tomcat-maven-plugin. 5. http://code.google.com/p/loof/.

Chapitre 8

Maven et JEE

137

Tester les EJB Notre projet EJB est lui aussi un lment assez dlicat tester confortablement. Le cycle de vie de lEJB doit tre respect pour que son code fonctionne et il repose sur la fourniture par lenvironnement de ressources gres par le serveur. Nous avons dcoup notre code pour pouvoir tester unitairement les aspects essentiels, mais nous voudrions pouvoir lexcuter en mode EJB rel, au moins pour quelques tests densemble. Une fois de plus, la force dune norme comme JEE va apporter des solutions. Comme nous ne dveloppons pas du code dpendant dun serveur particulier, nous pouvons le changer denvironnement pour le tester. La portabilit est garantie par la certication JEE qui valide le respect de la norme par chaque serveur JEE candidat. OpenEJB nous propose de dployer notre EJB dans un environnement particulirement lger, tel point quon peut facilement lintgrer dans un test unitaire. La seule chose que nous ayons faire, cest de lancer lannuaire JNDI dOpenEJB, qui se chargera automatiquement dans la foule. Le Listing 8.7 montre, par exemple, le code excessivement complexe qui permet de lancer notre EJB au sein dun test unitaire.
Listing 8.7 : Lancement dOpenEJB embarqu dans un test
@Test Public void testMonEJB() throws Exception { Properties p = new Properties(); p.setProperty( Context.INITIAL_CONTEXT_FACTORY, "org.apache.openejb.client.LocalInitialContextFactory" ); InitialContext ctx = new InitialContext( p ); MonEjb ejb = (MonEjb) ctx.lookup( "MonEJBLocalBean" ); // Test sur lejb... }

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 conguration 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 dnit cette norme a donn une nouvelle impulsion qui inue fortement sur la faon de dvelopper pour la plateforme JEE. Parmi les nombreuses nouveauts introduites pour simplier le dveloppement, allger la construction dune application ou dnir des comportements par dfaut qui vitent une longue phase de conguration, 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 sufsent dnir 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 clarication du projet, mais nous navons plus besoin de dnir 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 suft de congurer le mode inplace sur notre application web et de lancer le serveur. Notre EJB bncie 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 suft 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-glasssh-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 simplient les dveloppements ou amliorent la productivit. Une fois de plus, Maven ne fait que catalyser, grce une srie de plugins ofciels ou externes, les bonnes ides de dveloppeurs du monde entier. Lintgration en quelques lignes de XML des meilleurs outils du moment est pour lutilisateur nal 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 dnir 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 conguration dEclipse, lIDE le plus couramment utilis par les dveloppeurs. Lide est dextraire du chier POM toutes les informations ncessaires pour congurer lenvironnement Eclipse, ses nombreuses fonctionnalits et extensions. Le format des chiers de conguration 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

chiers de conguration ncessaire et exclure automatiquement la dpendance vers la bibliothque runtime aspectjrt.jar, qui est intgre dans AJDT. Limport des projets Maven se passe bien, et Nicolas est satisfait jusqu ce quil tente de dmarrer son serveur Web Tomcat.
java.lang.NoClassDefFoundError: org/aspectj/weaver/reflect/ReflectionWorld$Reflection WorldException

Ce ntait, semble-t-il pas, une si bonne ide de tout miser sur AJDT. Un magnique hack permet de contourner le problme en paramtrant le plugin avec ajdtVersion=none, an de dsactiver articiellement 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, lafuence 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 conguration dEclipse reste incomplte et ncessite encore et toujours soit des manipulations complmentaires dans lIDE, soit lajout de blocs entiers de conguration 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 conance lIDE pour analyser le chier 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

Maven et les IDE

143

Notre concours repose sur quelques critres pour ne pas fausser le jeu :
m m m m

transparence de limport dun projet Maven dans lenvironnement de dveloppement ; facilit de prise en main ; gestion des mtadonnes du chier POM en dehors du seul diteur XML ; intgration des plugins Maven dans la construction du projet par lenvironnement de dveloppement ; 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 planies 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 chier POM, identie correctement les rpertoires de code source, ainsi que ceux associs des gnrateurs de code quil excute automatiquement. Il est galement capable de congurer
1. http://www.eclipse.org/m2e/. 2. http://www.eclipse.org/iam/.

144

Maven en entreprise

Partie II

lenvironnement de programmation oriente aspect AspectJ, si celui-ci est install, ou dtablir un lien avec les gestionnaires de code source CVS et Subversion si le plugin adquat est install sous Eclipse. Aprs import, lensemble des dpendances Maven apparat dans un conteneur ddi, au ct de lenvironnement dexcution Java. LIDE ne diffrencie cependant pas les dpendances de scope test. Dun simple clic, on peut demander au plugin de tlcharger les archives de sources des dpendances, ce qui permet le cas chant de poser des points darrt avec le dbogueur dans les classes manipules. Limport peut galement seffectuer directement depuis le gestionnaire de code source dont on saisit lURL. Cette possibilit est utilise dans une fonctionnalit annexe qui consiste matrialiser une dpendance sous forme dun nouveau projet dans lenvironnement, condition bien sr que la dpendance en question dclare dans son POM le chemin correct de son gestionnaire de code source. Dans tous les cas, les dpendances dont le projet est prsent dans lespace de travail dEclipse sont rfrences comme projet, et non via larchive JAR, permettant de tester rapidement limpact dune modication. Prise en main Une nouvelle entre dans le menu contextuel nous permet dexcuter les tches lies Maven. Nos projets Maven sont reconnus et dcors dune petite icne "M" ; quant notre POM, il a droit une icne ddie qui permet de facilement le diffrencier des autres chiers du projet (voir Figure 9.1).
INFO Le plugin peut tre congur pour utiliser votre propre installation de Maven pour les tches courantes, mais dispose par dfaut dune copie interne de Maven quil utilise pour analyser le chier POM. Il sagit cependant dune version de Maven 3.x encore en cours de dveloppement, aussi il est prfrable pour viter toute mauvaise surprise de pointer sur linstallation locale de Maven 2.

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

Maven et les IDE

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 identiants 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 didentier 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 justier son statut dexpert Maven. La vue XML bncie 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 conguration de quelques plugins rcurrents, comme pour les plugins war ou aspectj. Lutilisateur peut dailleurs dnir 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 identiants de groupe, dartefact et les versions.

146

Maven en entreprise

Partie II

Figure 9.2 Gestion des dpendances.

La conguration des plugins, qui se fait exclusivement dans la vue XML, est, elle aussi, assiste : m2eclipse identie 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 conguration des plugins.

Chapitre 9

Maven et les IDE

147

Intgration des plugins Maven Lors de limport du projet, m2eclipse lit la conguration de quelques plugins cls pour adapter le paramtrage du projet en consquence. Le plugin compiler permet ainsi de dnir lenvironnement dexcution Java associ au projet. Ce support peut mme tre tendu par des plugins complmentaires qui exploitent les API de m2eclipse. Cest par exemple le cas pour le plugin Eclipse-cs qui exploite la conguration du plugin checkstyle de Maven pour aligner les deux environnements. Lors de la construction du projet dans lenvironnement de dveloppement, m2eclipse excute les plugins Maven associs aux premires phases du cycle de vie, en particulier les gnrateurs de code et de ressources. Cela lui permet didentier les rpertoires de code gnr mais a pour effet de bord dtre assez fortement consommateur en ressources : chaque modication ou sauvegarde dun chier de ressource ou dune classe, lIDE lance une construction qui se traduit donc par une excution de Maven. Selon le nombre de plugins concerns et leur rapidit, cela peut vite devenir pnalisant comme le montre la Figure 9.4 : lIDE se ge en attendant la n de cette excution, et afche le message trs agaant "user operation waiting for building workspace to complete". Il sagit dune limite de lIDE dans sa gestion des tches de fond et de la construction incrmentale des projets, et celle-ci peut devenir trs gnante pour son utilisation quotidienne. Les choses devraient aller mieux avec la prochaine version du plugin m2eclipse

Figure 9.4 Veuillez patienter

148

Maven en entreprise

Partie II

INFO Mme si lquipe Maven na pas les moyens de faire plier signicativement 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 spciques 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 dnissent 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 nir 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

Maven et les IDE

149

Interrogations Les versions successives de m2eclipse apportent corrections et nouvelles fonctionnalits et montrent un rel dynamisme pour proposer une intgration able 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 prols 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 vrier le bon fonctionnement de la machine caf. Aprs cette premire tape incontournable, Idea prsente chaque module du projet comme un projet Java, en ayant identi 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 dnies 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 identis 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 chier POM se fait via sa reprsentation XML, avec cependant de nombreux assistants. Idea identie, 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 identiants dune dpendance ou dun plugin. Ces rfrences agissent comme des hyperliens et permettent de naviguer dans les POM du projet de manire uide. 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 conguration du module (au sens Idea du terme) rete 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 conguration Idea ne sera plus synchrone avec le projet Maven. De la mme faon, les dpendances du projet sont clairement identies, avec un petit rafnement 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

Maven et les IDE

151

Figure 9.7 La conguration 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

Intgration des plugins Maven Les plugins qui gnrent du code lors des premires phases de la construction du projet sont invoqus lors de limport du projet, ce qui permet Idea didentier les rpertoires associs. Pour le reste, Idea ne sait pas exploiter la conguration des plugins Maven pour ajuster la conguration des siens. Le dveloppeur doit donc manuellement congurer le plugin Idea Checkstyle pour sadapter aux rgles dclares dans son POM. Cette restriction est valable pour tous les IDE, car elle demande au dveloppeur de chaque plugin pour un environnement donn de faire leffort de sinterfacer avec le support Maven, autrement dit de mettre un pied dans trois mondes diffrents (Maven, lIDE et loutil support par le plugin). Une telle gymnastique nest pas facile et est gnralement rserve aux outils majoritaires pour lesquels leffort en vaut la chandelle. Ce rsultat en demi-teinte est rapidement compens par la dmonstration que nous fait Stphane de lutilisation courante de lIDE. Il dite quelques classes, ajoute des dpendances, puis lance un test. Dans tous les cas, lenvironnement rpond promptement et ajuste sa conguration en fonction des directives du POM. Stphane rsume les choses en disant quil marche, "tout simplement", faisant rfrence son rival Eclipse dont le building workspace namuse plus personne. Bonus Lintgration de Maven dans Idea se fait donc sans oriture visuelle qui sorte du lot, mais tout simplement avec une solution totalement fonctionnelle et parfaitement intgre dans le fonctionnement de lIDE. Contrairement ce qui se passait avec Eclipse, nous navons pas limpression de voir sexcuter une surcouche au-dessus de lenvironnement qui tenterait de faire le lien entre deux mondes. Cest bien notre IDE qui sait parler le Maven, peut-tre pas dans toutes ses subtilits mais bien assez pour nous permettre de travailler confortablement. Nicolas grogne un peu dans son coin, se demandant sil a choisi le bon camp, mais il est vite repch par une question du jury : si les quipes sont habitues Eclipse, largement diffus dans les entreprises, lapprentissage dIdea est-il rapide ? Il faut bien ladmettre, apprivoiser un nouvel IDE prend du temps et les raccourcis que nous avons mis tant de temps mmoriser sont dsormais bien ancrs. Certes, le support de Maven dans Idea semble trs bon, mais entre le cot de licence, le cot de (re)formation et lventuelle perte de productivit des dveloppeurs contraints migrer, il va falloir faire passer la pilule !

Chapitre 9

Maven et les IDE

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 efcace, 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 conguration comme le font Eclipse ou Idea, mais il va entirement se baser sur le POM. Nous sommes ainsi assurs que les modications 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 modier la conguration 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 suft 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 spcique 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 spcicit dEclipse, que certains apprcieront mais laquelle dautres, comme Raphal, prfreront un environnement rellement fonctionnel. Une rapide dmonstration de dveloppement suft 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

Maven et les IDE

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 n 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 nit 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 suft 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 inuence sur le projet, de mme que Raphal travaille sous Linux.

156

Maven en entreprise

Partie II

Les choses tournent donc rapidement au consensus et se terminent autour du verre de lamiti (on la chapp belle, nest-ce pas ?).

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 inuence 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 identier tous les bogues qui auraient pu nous chapper. Les derniers correctifs sont appliqus, avant de se lancer dans une ultime journe de vrication pour tre sr de ne rien laisser au hasard. Aprs quoi, il nous faut prparer le logiciel enn stabilis et valid pour la diffusion. Emmanuel prend en charge la prparation de cette toute premire mouture. Il commence par parcourir tous les chiers de conguration du projet pour indiquer comme numro de version la fameuse valeur 1.0.0. Le projet, reconstruit avec cette nouvelle conguration, 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 modications 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 sufsait 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 sufrait dapporter les corrections ncessaires, de poser un nouveau tag et de reprendre la procdure. Troisime livraison Les choses semblent enn 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 prol 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 prol ddi, comme nous lavons vu au Chapitre 4. tait-ce une fausse bonne ide ? Lquipe de dveloppement, malgr le asco de cette version corrective, nen est pas convaincue. Les prols 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 prols adquats pour valider au maximum lapplication. Nous pouvons mme ajouter, cette phase cruciale, des prols spciques 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 enn une procdure de livraison able et connue de tous ?

Chapitre 10

Le jour J : la livraison

159

Documentation La procdure peut tre aussi btonne quon le voudra, elle nest able 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 modi, 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 Conuence, en passant par lincontournable XWiki cher Vincent.

Emmanuel documente ainsi la procdure de livraison dans notre wiki, accessible rapidement et sans les ambiguts dune classication 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 bncier 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 able 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 modication non sauvegarde dans le gestionnaire de code source. Optionnellement, un accs exclusif au gestionnaire peut tre demand pour les plus paranoaques dentre nous. Il contrle le projet qui ne doit rfrencer aucune dpendance en SNAPSHOT, dont ltat serait par nature non reproductible. Il modie les indications de version dans les chiers POM des modules du projet. Le plugin peut tre congur pour affecter la mme version toutes les branches dun projet multimodule, sinon il demandera de saisir une version pour chacun deux. Il indique dans le POM du projet le tag appliqu la version produire. Le projet comptera donc une rfrence explicite lemplacement o son code source est stock. Il effectue une construction complte du projet pour contrler les modications appliques automatiquement et sassurer quelles nont pas un impact ngatif. Il sauvegarde les modications appliques dans le gestionnaire de code source. Il pose un tag dans le gestionnaire de code source pour la livraison en cours de prparation. Il modie nouveau les indications de version pour pointer vers la version de dveloppement suivante et les sauvegarde.

m m

Comme vous pouvez le constater, la dmarche est plus que rigoureuse et elle est entirement automatise. Au nal, le projet dispose, dans son gestionnaire de versions, dun

Chapitre 10

Le jour J : la livraison

161

tag pour la version livrer, et la version courante (trunk) correspond la prochaine version dvelopper. Ltat "version livre" nest apparu que furtivement dans lhistorique du gestionnaire de code source, ce qui correspond bien la ralit de cet vnement aussi ponctuel que capital. tape 2 : livraison La production du logiciel livrable est ralise partir du tag plac dans le gestionnaire de sources. Nous pourrions effectuer cette manuvre manuellement, mais ici encore le plugin release simplie la tche :
m

extraction du code correspondant au tag dans un rpertoire ddi, vierge de toute modication locale malencontreuse ; construction du projet partir dune liste de cibles, doptions et de prols indiqus dans le POM.

Le point capital ici est que la description de la conguration 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 efcacit : 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 modication soit applique dans le gestionnaire de code source, le temps de bien mettre au point la conguration du plugin.

162

Maven en entreprise

Partie II

Vrification quil ny a pas de changement local

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

Tag des sources

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 identi 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

Reprendre la procdure partir du point o elle sest arrte prcdemment.

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 sufsamment de mmoire lexcution de Maven. Dans les deux cas, la rsolution du problme ne ncessite pas de modier 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 n, 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 chier, 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 able.

Tester des candidats


Jusqu prsent, nous avons utilis notre outillage de tests automatis et une srie de tests en amont pour valider le fonctionnement de notre logiciel avant livraison. Nous ne sommes cependant jamais labri dune coquille de dernire minute qui passerait au

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 ofcielle 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 rednir 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 insufsant pour rpondre nos exigences, il nous suft 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 sufra 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, abilise 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 signicatifs 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 dnitivement 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 l 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 congurer le serveur dintgration continue pour scruter lavancement de ce dveloppement parallle. Sous Hudson, nous pouvons simplement copier la conguration existante pour crer un nouveau job. Seul lemplacement du gestionnaire de code source sera modi. 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.

Au-del de lintgration continue


Nous avons dj mis en uvre lautomatisation de notre construction de projet au sein dun serveur dintgration continue. Maintenant que nous savons tout aussi bien automatiser la construction de nos livrables, il est naturel de franchir un pas supplmentaire. On parle parfois de production continue pour dcrire cette nouvelle tape dans lautomatisation, et cest une pratique qui sinscrit dans la dmarche dusine logicielle que de nombreuses entreprises cherchent appliquer leurs dveloppements informatiques pour chapper un monde o rgnent le bricolage et les manipulations manuelles hasardeuses. La Figure 10.3 prsente le principe gnral de cette approche.

Chapitre 10

Le jour J : la livraison

167

DVD ROM

CDRROM W

HD

Power

Build Local Gestionnaire de sources


DVD ROM CDRROM W
HD Power

Dploiement Plateforme de tests fonctionnels

Build Local

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 nal 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

Lintgralit du processus de ralisation de notre logiciel est ainsi embarque dans le POM. Les tches de construction, de test, de validation de nos rgles de dveloppement, de qualication, de contrle fonctionnel et dinstallation sont entirement automatises et ne dpendent plus que de la dcision de ladministrateur de cliquer sur le bouton vert, ou plutt de lancer un mvn Pproduction monserver:deploy.

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 enn 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 spcicit de votre projet tant automatise, documente et historise via votre chier POM, vous pourrez enn 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 exible 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 liale 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 spciques 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 identie ds la conception du code le non-respect de ces rgles.

172

Encore plus loin avec Maven

Partie III

Notre projet, venant du monde extrieur, a d passer par cette moulinette pour identier 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 spcique. 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 chiers sources .java analyser. Il faut galement que le classpath soit congur 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 chier POM fournissant les mtadonnes adquates, en particulier la liste prcise de ses dpendances. Nous avons dj voqu au Chapitre 2 lidentication des bibliothques et de leur version. Herv prpare soigneusement un chier 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 conguration que nous avons ajoute au projet pour grer cette tape.

Chapitre 11

Utiliser un outil non support

173

Listing 11.1 : Utilisation du plugin AntRun


<plugin> <artifactId>maven-antrun-plugin</artifatcId> <version>1.3</version> <executions> <execution> <goals> <goal>run</goal> <goals> <phase>site</phase> <configuration> <tasks> <classpath id="cp"> <pathElement ref="${maven.plugin.dependencies}"/> <pathElement ref="${maven.compile.dependencies}"/> </classpath> <taskdef task="check" class="com.geegol.GeegolProjectPlatformCheck" classpathRef="cp"/> <check src="${project.build.sourceDirectory}" out="${project.build.directory}/check"/> </tasks> </configuration> <dependencies> <dependency> <groupId>com.geegol.gea</groupId> <artifactId>geacheck</artifactId> <version>1.2.0</version> </dependency> </dependencies> </execution> </executions> </plugin>

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 spcique, 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

Encore plus loin avec Maven

Partie III

INFO Dans le Listing 11.1, nous navons pas indiqu didentiant de groupe pour dclarer le plugin. Maven utilise en effet une liste de groupes pour identier 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 ofcielles de plugins de la communaut des dveloppeurs Maven. Cette liste peut tre enrichie de nouvelles entres (via leur identiant de groupe) dans le chier de conguration de Maven : settings.xml. Si votre entreprise utilise de nombreux plugins maison, ce mcanisme peut vous aider allger votre conguration, cependant cela suppose que chaque dveloppeur dispose dun chier settings.xml correctement congur.

Retour dans un monde de scripts ? Cette solution est trs pratique car elle permet de rutiliser en peu de temps du code existant. Dans la mme veine, nous pourrions excuter un script Groovy ou BeanShell. Cependant, cette pratique nest pas tout fait satisfaisante : Herv nest pas prt se contenter de cette solution qui nest, pour lui, quun pis-aller : dune part, nous sacrions lide phare de Maven de ne pas devenir un nime langage de script. O est lapproche dclarative dans ce que nous venons de faire ? Dautre part, lintgration de notre bout de script Ant dans Maven est trs imparfaite. Nous devons explicitement dclarer les dpendances de loutil de gnration dans notre chier POM ce qui signie que nous devons les connatre, donc aller consulter sa documentation pour en extraire cette information. Cela ne vous rappelle rien ? Alors, retournez au Chapitre 2 !
AntRun a t conu comme un outil de transition pour faciliter la vie des projets bass sur Ant. Les concepteurs de Maven, conscients quil tait impossible de proposer des plugins pour toutes les tches Ant existantes, ont introduit ce plugin utilitaire, en insistant bien sur son rle de roue de secours en attendant mieux. Nous lutilisons donc provisoirement pour rpondre aux exigences du groupe, mais lanons immdiatement une nouvelle tche : lcriture dun plugin Maven pour notre outil de gnration documentaire. Cest donc cette tche quHerv va sattaquer prsent.

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

Utiliser un outil non support

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

Listing 11.2 : En-tte POM du plugin documentaire


<modelVersion>4.0.0</modelVersion> <groupId>com.geegol.maven.plugins</groupId> <artifactId>geegol-doc-maven-plugin</artifactId> <version>1.0-SNAPSHOT</version> <packaging>maven-plugin</packaging> <name>Plugin de contrle GEA</name>

Le reste du projet est tout ce quil y a de plus classique. Rpertoires de sources, de ressources et de tests, dpendances et compagnie. Pas de quoi fouetter un chat ! La tche check que nous voulons crer dans notre plugin sera associe une classe spcique. Ces classes sont appeles dans le vocabulaire Maven des mojos (Maven Old Java Object), par allusion au concept de POJO1 qui a fait le succs des bibliothques Spring et Hibernate. Ce terme a aussi t choisi avec malice pour faire rfrence au nom donn au Cameroun des amulettes inutile de chercher un lien avec le personnage de super-vilain associ ce nom dans le comics X-Men ;-). En fait, ce sont de simples classes qui implmentent linterface org.apache.maven.plugin.Mojo, et, dans la trs grande majorit des cas dont le ntre , on se contente dtendre la classe AbstractMojo. Le Listing 11.3 prsente la structure gnrale de notre classe GEACheckMojo.

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

Encore plus loin avec Maven

Partie III

Listing 11.3 : Notre classe Mojo de base


/** * Tche de gnration de la documentation au format Geegol. * * @goal check * @phase process-sources */ public class GEACheckMojo extends AbstractMojo { public void execute() throws MojoExecutionException { // ... } }

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 chier de compte-rendu. Herv va dans un premier temps permettre lutilisateur de dnir le nom et lemplacement de ce chier, 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

Utiliser un outil non support

177

Comme la conguration gnrale du Mojo, les paramtres sont dclars via des annotations " lancienne" dans le Javadoc (aussi connu sous le nom de doclets). Chaque paramtre peut dnir 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 chier POM. Dans lexemple prcdent, nous identions par exemple le paramtre output o loutil danalyse va crire son rapport. Les utilisateurs de notre plugin pourront modier ce paramtre dans leur chier POM en ajoutant dans la conguration un lment <output> avec le chemin de leur choix. Lexpression dlimite par "${" et "}" permet didentier 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 prols. project.build.directory quivaut ainsi llment <project><build><directory> du chier 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 signie 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 er 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

Encore plus loin avec Maven

Partie III

Un projet Maven comprend, au niveau du modle du projet, non pas un rpertoire source mais une liste dynamique demplacements. Chaque plugin qui gnre du code source va ajouter le rpertoire quil utilise sur cette liste. De la mme faon, les plugins qui exploitent le code source, commencer par le plugin de compilation, vont reposer sur cette liste dynamique de rpertoires. Pour accder au modle objet du projet et consulter le moment voulu cette liste de rpertoires, nous devons manipuler directement lobjet MavenProject que Maven met notre disposition. Nous dnissons donc un nouveau paramtre au plugin, bien que celui-ci soit un peu particulier :
/** * Modle objet du projet Maven * @parameter expression=${project} * @required * @readonly */ private MavenProject project;

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 conguration est incomplte, et @readonly signale que le paramtre est extrait des structures internes de Maven et non spci 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 chiers 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

Utiliser un outil non support

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 identi 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 lidenticateur par un qualicateur complmentaire identi 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;

Il faudra videmment ajouter notre plugin une dpendance vers la bibliothque plexus-archiver qui contient ce composant. Lcosystme Plexus compte de trs nombreux composants, permettant de traiter un grand nombre de tches. La documentation de ces composants est malheureusement souvent un peu minimaliste, et mme leur liste complte est dlicate obtenir en dehors du code source sous SVN.

2. http://plexus.codehaus.org/. 3. Aussi connu sous le nom Inversion_de_contrle).

dInversion

de

Contrle

(http://fr.wikipedia.org/wiki/

180

Encore plus loin avec Maven

Partie III

Plexus-utils En plus des composants Plexus, Herv a besoin de faire de nombreuses manipulations de chiers, entre autres pour slectionner la liste des chiers .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 chiers FileUtils ainsi quun DirectoryScanner, qui permet de slectionner des chiers 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 chiers sources Java de notre projet, code gnr inclus ! Reste passer loutil de contrle Geegol dessus. Des classes et des royaumes Une difcult 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 dnit 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

Utiliser un outil non support

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 conguration 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 gpp.jar plexus-utils plexus-archiver maven-plugin-api

Royaume gea-check

Construit par le plugin


GEACheck.jar target/classes

MavenProject

Figure 11.1 Arbre des royaumes ClassWorlds.

Le Listing 11.4 montre le code du plugin pour :


m m m m

construire un nouveau ClassLoader (chargeur de classe) ; lui associer les dpendances et rpertoires du projet sur lequel il travaille ; lui associer la bibliothque de loutil que nous voulons excuter ; excuter loutil GEACheck lintrieur de ce contexte.

182

Encore plus loin avec Maven

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 difcult rencontre lors du dveloppement dun plugin Maven, dune part parce que le commun des dveloppeurs nest pas sufsamment 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

Utiliser un outil non support

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 chiers sources java que nous avons construite prcdemment. Linvocation dune classe depuis un classloader diffrent du ntre nous oblige passer par la rexion 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 chiers. Notre ami Guillaume, grand fan de Groovy, relve le d et nous propose une version "groovye" de notre plugin (voir Listing 11.6).

184

Encore plus loin avec Maven

Partie III

Listing 11.6 : Le mojo GEACheck en version Groovy


/** * Tche de gnration de la documentation au format Geegol. * * @goal check * @phase process-sources */ class GEACheckMojo extends AbstractMojo { /** * Emplacement du fichier de compte-rendu * @parameter default-value="${project.build.directory}/check.html" */ private output /** * Modle objet du projet Maven * @parameter expression="${projet}"" * @required * @readonly */ private project /** * Permet de manipuler des archives ZIP * * @component role="org.codehaus.plexus.archiver.Archiver" hint="zip" */ private zipArchiver /** * Dpendances du projet Maven qui utilise le plugin * @parameter expression="${project.compileArtifacts}" */ private projectArtifacts /* * * Dpendances du plugin lui-mme * @parameter expression="${pluginArtifacts}" */ private pluginArtifacts private getJavaSources( File root ) { def scanner = new DirectoryScanner( basedir: root, includes: [ "**/*.java" ] as String[] ) scanner.scan() return scanner.includedFiles.collect { relativeFilePath -> new File( root, relativeFilePath ) } }

Chapitre 11

Utiliser un outil non support

185

public ClassLoader createClassLoader() throws MalformedURLException,

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 ); } } }

Tester notre plugin


Herv est er de nous montrer le fonctionnement de son plugin, qui a ncessit quelques acrobaties techniques avec les ClassLoaders mais qui ntait nalement pas si compliqu que a dvelopper, une fois ces bases acquises. Par contre, il garde un mauvais souvenir de sa premire dmo pour laquelle le rsultat tait incomplet. Il voudrait que son projet de plugin puisse tre quip de tests, comme tout bon projet Maven ! Un moyen simple de tester le plugin est de lassembler sous forme de JAR et de linvoquer manuellement depuis lun de nos projets. Nous avons cependant pris lhabitude des tests automatiss et de leur intrt pour assurer la stabilit de nos dveloppements. Lcosystme Maven propose plusieurs options pour outiller de tests notre plugin. Du fait que celui-ci pourra tre utilis sur de nombreux projets, sa stabilit est indispensable et une rgression peut tre trs pnalisante, aussi, un outillage de tests est indispensable.

186

Encore plus loin avec Maven

Partie III

Il faut avouer que les plugins Maven ofciels 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 difcult pour tester un plugin Maven rside dans lidentication 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 congurer une instance du plugin tester. Un extrait de fichier POM est utilis pour dnir la conguration 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 congurer 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 vrier son fonctionnement. Le Listing 11.8 montre le pseudo-chier POM qui lui sert de base pour construire et congurer 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

Utiliser un outil non support

187

mojo.execute(); File expected = new File(getBasedir(), "target/test-target/check/repport.html" ); assertTrue( "expected file not found", expected.exists() ); } }

Listing 11.8 : Pseudo-POM charg lors du test


<project> <build> <plugins> <plugin> <groupId>com.geegol.maven.plugins</groupId> <artifactId>geacheck-maven-plugin</artifactId> <configuration> <outputDirectory>target/test-target/check</outputDirectory> </configuration> </plugin> </plugins> </build> </project>

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 chiers POM placs dans le rpertoire de tests src/it, invoker va utiliser un script Groovy ou BeanShell pour vrier le rsultat de lexcution. Ce script va typiquement sassurer que des chiers attendus en rsultat de lexcution sont prsents et/ou correctement renseigns.

188

Encore plus loin avec Maven

Partie III

Le Listing 11.9 prsente la conguration du plugin invoker pour excuter un projet Maven de test. Le plugin recherche dans notre rpertoire src/it tous les sous-rpertoires contenant un chier pom.xml, les recopie dans le rpertoire de travail et y excute un build Maven (jusqu la phase package). Nous pouvons donc organiser notre rpertoire de tests dintgration en ayant un sous-rpertoire par test dintgration, contenant le projet Maven dintgration tester. Le Listing 11.10, quant lui, prsente le chier groovy que nous utilisons pour vrier que lexcution sest droule comme prvu et que le fonctionnement du plugin est donc correct.
Listing 11.9 : Configuration du plugin invoker
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-invoker-plugin</artifactId> <version>1.3</version> <configuration> <postBuildHookScript>verify</postBuildHookScript> <localRepositoryPath>${project.build.directory}/it-repo</localRepositoryPath> <settingsFile>src/it/settings.xml</settingsFile> <cloneProjectsTo>${project.build.directory}/it</cloneProjectsTo> </configuration> <executions> <execution> <goals> <goal>install</goal> <goal>run</goal> </goals> </execution> </executions> </plugin>

Listing 11.10 : Script Groovy de contrle de lexcution


// GEACheck doit gnrer son rapport sous target/check assert new File( basedir, target/check/report.html ).exists(); return true;

Herv congure le serveur dintgration continue pour surveiller, en plus de notre projet, la bonne sant de son plugin, lequel, outill de tests, est maintenant prt pour vivre sa vie et rpondre au besoin des demandes dvolution ou de nouvelles contraintes. Herv na plus qu documenter ce plugin et son utilisation mais pour cela il devra attendre le chapitre suivant !

Chapitre 11

Utiliser un outil non support

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 vrier ont t choisies et pondres selon des critres propres lentreprise, mais au moins elles sont clairement identies et justies. 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

Encore plus loin avec Maven

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 identi, il veut tre capable de rpondre :
m

que nous lavons galement identi, ventuellement avec un poids diffrent, et sommes donc tout fait en mesure de le traiter ; que nous disposons de loutillage ncessaire pour nous assurer quil ne se reproduise plus ; que nous sommes en mesure de fournir des indicateurs dmontrant lamlioration progressive de notre code sur la base des critres identis par les responsables qualit.

Avec un dossier de dfense aussi bien cel, 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 ert, 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

une liste dalertes signalant des mauvaises pratiques connues, tournures de code maladroites ou bogues rcurrents lis limperfection des dveloppeurs qui tombent tous dans les mmes piges et aucun de nous ne fait exception ce constat ; des indicateurs sur la structure du code, jugeant sa modularit, sa complexit ou son niveau dabstraction.

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 identier tous les bogues si coteux que nous avons ngligemment laisss traner ?
Checkstyle

Vincent exprimente tout dabord un outil open-source de cette catgorie sur notre code : Checkstyle. Lanalyse est de niveau syntaxique et signale les incohrences qui existent dans notre faon de travailler. Une grande partie des rgles de Checkstyle concerne le formatage du code plus que son fond, loutil semble donc la fois tatillon et sans grand intrt. Lautre Vincent si vous avez bien suivi les chapitres prcdents, vous aurez not que notre quipe compte deux Vincent ;) , qui suit de loin le travail de son collgue par pauses-caf interposes, nest pas de cet avis. Il a pass deux heures fusionner ses dernires modications avec celles dHerv, non pas parce que ce dernier travaille comme un cochon (sans quoi, il ne serait pas dans lquipe !), mais tout simplement parce quil utilise des rgles de formatage de code diffrentes (voir Listing 12.1).

public class ListeDesCourses implements Data { private Set courses = new HashSet(); public void addCourse(String course) throws IllegalStateException { courses.add(course); } public Collection getCourses() { return courses; }

public class ListeDesCourses implements Data { private Set courses = new HashSet(); public void addCourse( String course ) throws IllegalStateException { courses.add( course ); } public Collection getCourses() { return courses; }

La diffrence entre ces deux chiers sources est minime, cependant les outils de fusion automatique ne savent pas la grer et obligent Vincent vrier ligne par ligne la concordance des deux versions concurrentes.

194

Encore plus loin avec Maven

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 supercielles, 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 dnissons un niveau de documentation que nous considrons souhaitable pour notre projet, Checkstyle saura indiquer nos points faibles ou notre relchement. Enn, 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 afner 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

Vincent poursuit son exprimentation sur lanalyse statique du code avec FindBugs. Comme son nom lindique, cet outil se propose de trouver tout seul les bogues dans notre code, lesquels correspondent des patrons de codage fragiles et viter. Mme si un dveloppeur expriment en est conscient, il risque de les mettre en uvre par mgarde.

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 identier. 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 dnies en marge du livre Programmation concurrente en Java, de Brian Goetz chez le mme diteur, excellent ouvrage que je vous recommande ;) pour identier les problmes de gestion concurrente en environnement multithread.
PMD

Vincent termine son tour dhorizon en installant un autre outil danalyse statique : PMD. Celui-ci se place mi-chemin entre Checkstyle et FindBugs. Moins formel que Checkstyle, il ne propose pas des rgles aussi pousses que FindBugs (aid par des annotations). Cela ne signie pas pour autant quil soit inutile. Il vient renforcer la pertinence de lanalyse en proposant un autre regard sur notre code. Il nous reste cependant dnir soigneusement ses rgles danalyse pour quelles soient cohrentes avec nos deux autres outils ! Analyse dynamique Les outils danalyse statique font dj de grandes choses mais ils ne peuvent pas faire de miracle. En particulier, ils ne sont pas en mesure de deviner comment est utilise rellement lapplication. Pour cela, il faut la faire tourner dans un environnement et une utilisation ralistes. Or, nous avons dj, depuis le Chapitre 4, une belle panoplie de tests qui excutent notre application, par petits morceaux, en se focalisant sur des

196

Encore plus loin avec Maven

Partie III

scnarios dutilisation issus de nos besoins fonctionnels (rappelez-vous les rgles du dveloppement dirig par les tests !). Cobertura, Clover ou Emma sont des outils danalyse dynamique qui visent dterminer quelle portion de notre code est excute au cours de nos tests, censs couvrir les fonctionnalits de notre application. Leurs rapports indiquent le taux de couverture du code et remontent jusquau code source pour nous indiquer quelle ligne a t excute au moins une fois au cours dun test. Comment exploiter un tel outil ? Olivier, qui est venu pauler Vincent, value avec lui ces outils et linformation quils fournissent. Lindication synthtique est un taux de couverture de notre code par des tests : 65 %. Est-ce bien ou pas ? Brute, cette information na aucune utilit ou presque. Son intrt est plus de voir comment ces 65 % se rpartissent sur notre code. En descendant un niveau de dtail plus n, on dcouvre dans le rapport quune majorit de nos packages sont couverts environ 70 % et que deux mauvais lves se contentent de 30 %. Nous tenons nos coupables : deux packages pas assez tests, ou mal tests, ou peut-tre mme du code inutile !
m

Le premier, remoting, est celui de nos interfaces de communication avec dautres systmes. Pas le plus facile tester puisquil faut quelquun (un simulateur) en face pour rpondre et valider le fonctionnement du logiciel. 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.

Sur ce constat, reposons donc la question : comment exploiter un tel outil ? Si nous tablissons comme rgle dor le taux de couverture des tests doit dpasser 75 %, que va-t-il trs probablement se passer ? Vous pouvez parier que le package beans va rapidement tre test 100 % an datteindre ce taux de 75 %. Le dveloppeur tant par nature faignant, il choisira la solution de facilit, surtout si son chef lassomme de reproches sur le non-respect de la rgle dor ! Loutil fournissait pourtant une information capitale : remoting, couche critique de notre application, est celle qui est la moins bien teste. Il nous encourage effectivement retrousser nos manches pour mieux instrumenter ce code, peut-tre en le rarrangeant an quil soit plus modulaire et plus testable, peut-tre en dveloppant des simulateurs plus faciles intgrer dans un test unitaire.

Chapitre 12

Lassurance qualit

197

Vincent prend cela en considration et tablit notre premire rgle dor :

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.

Il considre ensuite le reste de lapplication : la couverture de code est homogne, mais est-elle sufsante ? Comment va-t-elle voluer ? Comment doit-elle voluer ? Si nos classes de JavaBeans gonent suite lajout de mthodes get/set, notre taux va irrmdiablement baisser mais ce ne sera pas signicatif. Par contre, si lajout de nouvelles fonctionnalits dgrade le taux de couverture, cest que ces nouvelles fonctionnalits ne sont pas au moins aussi bien testes que le code en place. Cela inspire donc une seconde rgle dor, que nous pourrions qualier de protectionniste :
Le taux de couverture ne doit pas baisser avec le temps sans justification.

Vincent arrive donc rapidement la conclusion quil va devoir trouver un moyen pour contrler lvolution dans le temps de nos indicateurs. tre capable destimer la couverture de test apporte des informations utiles, mais savoir si elle est en perte de vitesse et sur quels packages est bien plus important. Notre bote outils est dsormais comprise et correctement congure. Il reste Vincent automatiser son utilisation pour mettre ces indicateurs la disposition de tous et permettre leur suivi dans le temps. Lassurance qualit ne fonctionne que si elle est la proccupation de tous. Donner quelquun la tche de suivre les rapports danalyse na aucun sens, il passerait rapidement pour le casse-pieds de service. Mobiliser quelques instants dattention de toute lquipe est peu coteux individuellement et nettement plus efcace. Vincent pourrait continuer ainsi son tour de table des outils danalyse de code, mais toute cette instrumentation ne sera vraiment productive que si elle vient sintgrer dans nos outils. Nous avons dj con la construction de nos binaires Maven, pouvonsnous galement lui passer la main sur notre suivi qualit ?

198

Encore plus loin avec Maven

Partie III

Les rapports Maven


Comme toujours, lintgration de nos outils danalyse avec notre construction de projet Maven passe par des plugins. Nous pouvons, par exemple, lancer un mvn checkstyle:check pour vrier le respect de nos rgles de codage, voire le congurer pour quil sexcute durant un build normal si nous nous interdisons de ne pas suivre strictement ces rgles. videmment, cest encore plus efcace si un tel outil danalyse peut tre intgr dans lIDE et fournir au dveloppeur une alerte ds que la ligne de code est saisie ! Maven propose cependant une autre forme dintgration pour les outils qui visent complter la documentation sur le projet : les rapports. Notre projet est accompagn dune large documentation, expliquant son utilisation, ses rgles de dveloppement et lexplication de nos choix techniques. Reste la diffuser efcacement auprs de nos utilisateurs et contributeurs. Dans un premier temps, nous lavons place ct de notre projet dans le gestionnaire de sources. Lors dune livraison, nous accompagnons ainsi lexcutable de lapplication de sa documentation jour. Cette approche tout-en-un est pratique pour lutilisateur qui a tlcharg notre logiciel, mais pas pour celui qui vient juste de le dcouvrir et voudrait en savoir plus avant de poursuivre. Un site web serait alors une meilleure solution. Comment concilier ces deux formes de documentation ? Par ailleurs, nous sommes ers de notre systme qualit ; aussi voudrions-nous lexposer plus nos utilisateurs pour dmontrer notre savoir-faire et gagner leur conance. Enn, notre code tant soumis une licence libre, nous voulons quil soit aussi facilement consultable que possible pour permettre chacun de proposer des enrichissements. Aprs avoir test diverses solutions documentaires, Lukas cherche toujours un moyen pour synthtiser les diverses sources dinformation du projet. Dune part, notre wiki, dont la syntaxe simple permet de construire rapidement une documentation par enrichissement successif. Dautre part, nos outils danalyse qualit, dont les rapports sont instructifs sur nos mthodes de travail. Ensuite, des indications techniques sur notre projet : licence, prrequis, dpendances. Enn, une srie de liens sur les aspects communautaires de notre projet : quipe de dveloppement, liste de diffusion, systme de suivi des anomalies, etc. Agrger toutes ces informations sous un point dentre unique, toujours jour et homogne, voil une tche ambitieuse qui neffraie pas Lukas. Il dcouvre rapidement que Maven, lui-mme confront ce problme de documentation, offre une solution complte et trs riche : la gnration dune documentation

Chapitre 12

Lassurance qualit

199

complte du projet. En parallle du cycle de vie de construction du projet, Maven propose un cycle de vie documentaire dclench par la commande mvn site. Cette commande nexcute quun seul plugin, site, mais celui-ci est larbre qui cache la fort : son rle est dexcuter des rapports et den agrger le contenu dans un document uni sous forme de site web. Ces rapports sont eux-mmes dclars dans notre POM, sous un lment ddi <reporting>. Ils ressemblent sy mprendre des dclarations de plugins et sont dailleurs le plus souvent coupls avec un plugin Maven classique. Ils nont cependant pas exactement le mme fonctionnement et vont produire un rsultat (souvent un rapport brut en XML) que le plugin site va mettre en forme au sein du site du projet.
ASTUCE Un plugin de reporting ne tient pas compte des informations dclares dans le <pluginManagement>, balise qui permet de regrouper la conguration de tous les plugins utiliss sur un projet. Il est donc prfrable dutiliser une proprit pour ne pas dupliquer linformation de version et risquer de tomber dans des bogues tranges. Cette dernire sera utilise dans la dclaration du plugin dans la partie <pluginManagement> et dans la partie <reporting>. Par ailleurs, un plugin de reporting qui serait aussi utilis soit en ligne de commande, soit dans le cycle de vie du build, hrite toujours de la conguration dnie dans la partie <reports>. Aussi, dans ce cas, et uniquement dans celui-l, il est prfrable de dclarer sa conguration globale dans la partie <reporting> plutt que dutiliser le <pluginMana-

gement>.

Le plugin site se base sur un chier ddi, src/site/site.xml, dans lequel est dcrite la structure gnrale de notre site web. Ce chier 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

Encore plus loin avec Maven

Partie III

<item name="Maven" href="http://maven.apache.org/"/> </links> <menu name="Guide"> <item name="Introduction" href="user-guide/introduction.html"/> <item name="Setup" href="user-guide/setup.html"/> </menu> <menu ref="reports"/> </body> </project>

La structure simple de ce chier se passe de commentaires. Le seul point souligner est la prsence de la macrocommande <menu ref="reports"/> qui indique au plugin lemplacement o insrer les liens vers nos rapports danalyse du projet. Les pages de notre site peuvent tre crites au choix :
m

Selon un format APT (Almost Plain Text), proche dune syntaxe wiki et rapidement assimil. En exploitant les pages dun wiki Conuence, ou TWiki. Via le format documentaire DocBook (simpli). Via le format documentaire XDoc support de manire native. Tout simplement partir dun document xHTML. Ou encore, via un module dextension, en exploitant tout autre format. Le bac sable Maven comprend ainsi un module permettant dexploiter la syntaxe XWiki.

m m m m m

Au premier lancement de la commande mvn site, aprs linvitable tlchargement de nombreux plugins et bibliothques dans diverses versions, nous obtenons effectivement sous target/site la structure dun site web pour notre projet. La gnration de ce site est dlgue par le plugin site un sous-composant spcialis, Doxia1. Cet outil prend en charge toutes les conversions ncessaires entre les formats de documents supports et le document construire. Autre chose que du HTML Doxia est donc le moteur qui va formater notre documentation. Utilis par le plugin site, il produit des pages HTML. Utilis par le plugin pdf, il produit un chier PDF regroupant toute la documentation du projet. La commande mvn pdf:pdf permet ainsi de produire une documentation format papier, toujours jour en fonction des diverses sources que nous avons agrges.
1. http://maven.apache.org/doxia.

Chapitre 12

Lassurance qualit

201

Comme le plugin site et son chier 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 Doxia

Fichiers APT, xdoc, fml, ...

Maven-Site-Plugin PMD Checkstyle FindBugs Rapport Cobertura JavaDoc ... Site web Site.Xml

Projet Maven

Figure 12.1 Gnration de la documentation en diffrents formats grce Doxia.

Exploiter notre gestion documentaire


Nous sommes donc dsormais en mesure danalyser le code de notre projet avec laide dune large panoplie doutils et dagrger le rsultat dans une documentation complte par ce que nous aurons pris le temps de rdiger dans des formats varis, le tout en une seule commande comme Maven nous y a habitus.

202

Encore plus loin avec Maven

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 identier 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 chiers 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 modication 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 inchissement 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 didentier 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. 30 pieds, on accde au Top 10 des classes problme, et on commence regarder les noms des auteurs des dernires modications pour savoir avec qui il faudra discuter de manire aimable et constructive lors de la prochaine pause-caf. 1 mtre, on droule le code source ligne par ligne et on y identie 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.

Ce Google Earth pour code existe, il sappelle Sonar.

2. Petit rappel de vos lointains cours de physique : S est le symbole utilis en physique pour lentropie :).

204

Encore plus loin avec Maven

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 congurer 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

surface correspond un grand volume de code et la couleur au niveau de satisfaction du critre. Un petit bloc rouge dans un ensemble vert pourra donc tre acceptable si on sait le justier, alors quun grand bloc orange sera de trs mauvais augure. Chaque lment de cette synthse est un lien vers plus de dtails. On va ainsi descendre de lien en lien jusquaux classes du projet puis ouvrir son code source pour constater la ligne de code qui a t identie par lanalyse de code (voir Figure 12.3).

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 conguration de ce plugin dans notre POM. Le plugin sonar utilisant de nombreuses proprits, il est plus simple de les congurer 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

Encore plus loin avec Maven

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 conguration de cet outil dans notre POM. Il suft de fournir quelques paramtres dans la console dadministration de Hudson et de congurer une construction du projet heure xe. 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 linuence que peut avoir un petit effort quotidien de clarication et de simplication 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 dbrieng est dj toute trace ! Sonar nest dnitivement pas un outil de icage, 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 identies.

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 bnce. 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 congurer 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 signicatif. 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

Encore plus loin avec Maven

Partie III

Lukas a cependant fait les frais dune automatisation maladroite de ce processus. Lquipe de test vient de lui remonter une anomalie grave : audel de cinquante requtes par seconde, lapplication semble se ger et voit ses performances se dgrader vue dil. La version prcdente navait rencontr aucun souci de ce type, et il est donc urgent didentier le problme. Le premier rexe est de se demander ce qui a chang entre ces deux versions testes, et cest l que Lukas se retrouve seul face deux chiers EAR, sans aucune information lui permettant de faire rapidement le lien avec notre gestionnaire de code source. Pour pallier ce problme, nous devons disposer au sein de larchive EAR dune indication de lemplacement exact dans lhistorique de notre code do elle a t tire. Le mcanisme de marques (tag) dans le gestionnaire de code source est gnralement utilis cet effet pour faire le lien entre une version publie et son code source. Cependant, nous parlons ici de versions de tests que nous livrons une deux fois par semaine lanalyse froce de nos outils de tests de charge et dinteroprabilit. Toutes ces versions portent le mme numro 1.2.0-SNAPSHOT qui rete bien que le projet nest pas encore abouti. Numro de construction Une solution consiste produire des binaires dont le numro de version est complt par un compteur de construction, que le serveur dintgration continue incrmente chaque tentative de construction. Le serveur dintgration continue a le bon got de nous fournir la valeur courante sous forme dune variable systme, que nous pouvons donc exploiter dans le build Maven. Le Listing 13.1 montre la conguration de notre POM pour exploiter cette variable et produire les livrables en consquence. Nous utilisons un prol qui nest activ que sur le serveur dintgration continue, an de ne pas perturber les autres environnements.
Listing 13.1 : Exploiter le numro de construction de Hudson
<profile> <id>integration-continue</id> <build> <finalName>${project.artifactId}/${project.version}-build-${HUDSON_build}</finalName> </build> </profile>

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

Respecter un format de distribution

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 chier modi. On arrive ainsi rapidement des numros de rvision cinq ou six chiffres. Si cela na aucune inuence 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 suft 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

Encore plus loin avec Maven

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 chier. 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 modier le nom du chier 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 nal un chier noubliepaslalistedescourses-1.2.0-SNAPSHOT-rev-4704.ear, le chier 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 dnit aussi un mcanisme de mtadonnes via le rpertoire spcialis META-INF, et en particulier le descripteur MANIFEST.MF. Ce chier nest rien dautre quun chier texte, dont le formalisme est un peu droutant parfois mais qui ressemble globalement aux chiers 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 chier MANIFEST ? La construction de nos projets par Maven en produit naturellement un, avec des informations minimalistes. Il suft de demander aux plugins jar, war ou ear dajouter dautres informations. Le Listing 13.3 montre la conguration mise en place par Lukas pour aboutir une solution enn satisfaisante et pleinement reproductible. Notez aussi lutilisation dun prol 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

Respecter un format de distribution

213

Listing 13.3 : Ajout de mtadonnes dans le MANIFEST


<profile> <id>integration-continue</id> <build> <pluginManagement> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-war-plugin</artifactId> <configuration> <archive> <manifestEntries> <Build>${buildNumber}</Build> </manifestEntries> </archive> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jar-plugin</artifactId> <configuration> <archive> <manifestEntries> <Build>${buildNumber}</Build> </manifestEntries> </archive> </configuration> </plugin> </plugins> </pluginManagement> <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> </build> </profile>

214

Encore plus loin avec Maven

Partie III

Avec cette conguration, chacun de nos binaires portera dsormais les informations compltes de ses origines. En cas de besoin, il nous sufra de les exploiter pour retrouver rapidement le code source associ, et ventuellement les traces de sa construction dans notre serveur dintgration continue.

La conance 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, certi 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 able ? 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

Respecter un format de distribution

215

Faut-il prciser que Stphane sattendait de nombreuses questions, mais certainement pas celles-l. Sa prsentation tait oriente productivit, abilit, ractivit et travail dquipe, pas icage et suspicion. Il faut dire que notre quipe est compose de bons camarades et que nous ne connaissons pas les situations tendues de malveillances informatiques. Mais il est vrai quun JAR incluant des erreurs ou du code malicieux, qui se retrouve automatiquement install sur tous les postes de dveloppement avec laide du mcanisme de SNAPSHOT, peut faire perdre des journes entires de travail, multiplies par le nombre de dveloppeurs concerns La premire option est, bien sr, de scuriser notre dpt de bibliothques. Un compte et un mot de passe sont dsormais ncessaires pour pouvoir y dployer des binaires. Stphane est cependant un peu anxieux de retourner au casse-pipe avec cette seule rponse donner notre M. Scurit. Il cherche donc un moyen pour indiquer de manire infalsiable qui a produit une archive Java. La rponse lui vient indirectement dOlivier. Celui-ci a pris lhabitude de signer numriquement ses mails, sans doute plus pour le plaisir dinstaller lextension ncessaire son navigateur et dassumer ainsi son appartenance indiscutable au monde des geeks. Cette signature utilise lalgorithme GPG2, qui a le double avantage dtre libre et bas sur un couple de cls. La cl publique permet nimporte qui de valider lidentit de lauteur, qui conserve soigneusement sa cl prive hors de porte de tout intrus. Interrog sur le sujet, Olivier fait rapidement le lien avec le plugin GPG disponible pour Maven et qui permet de signer un binaire de la mme faon quil signe ses messages. Lauteur, dclar dans le chier MANIFEST, est donc facilement contrlable via sa cl publique. Le Listing 13.4 montre la conguration de ce plugin mis en place par Olivier et Stphane.
Listing 13.4 : Mise en place dune signature GPG
<project> ... <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-gpg-plugin</artifactId> <version>1.0-alpha-4</version> <executions> <execution>

2. http://fr.wikipedia.org/wiki/GPG.

216

Encore plus loin avec Maven

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 chier binaire sign numriquement par sa cl GPG. Voil de quoi donner du rpondant Stphane pour sa prochaine runion !

LEAR ne suft pas


Notre archive dentreprise EAR ne se suft pas. Elle doit tre complte par des chiers de conguration, dans lesquels devront tre indiqus des paramtres techniques dpendant de lenvironnement rseau, du systme hte, ou des ajustements lis la charge constate sur le serveur : nombre de threads allous nos tches de fond, time-out de connexion nos serveurs partenaires Pour des raisons dassurance qualit, nous devons galement accompagner notre application de tout le code source qui la compose. Cela peut sembler bien paranoaque, mais de trop nombreuses applications se sont retrouves en production alors que le code source tait malencontreusement gar, perdu au cours de la raffectation dun serveur de dveloppement ou de larchivage un peu rapide de nos supports de stockage.
INFO De nombreuses entreprises imposent pour la mme raison, dans leurs rgles qualit, de recompiler tout logiciel open-source introduit dans une application. Si cette rgle est rarement applique (hou, les vilains), vous devinez facilement de quelle exprience catastrophique elle peut provenir binaires non identis, sans code source, bugs impossibles reproduire et donc corriger. Le pass a du laisser certains de cruelles blessures.

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

Respecter un format de distribution

217

Assemblage du livrable La production rclame une archive Unix tar.gz rpondant une structure trs prcise :
m m

Larchive EAR doit tre place dans un sous-rpertoire application. Nos chiers de conguration doivent tre regroups dans un sous-rpertoire configuration. Le code source doit tre plac dans un sous-rpertoire sources.

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 chier XML qui dcrit le livrable assembler. Dans ce chier, nous indiquerons les constituants de notre archive. Le chier assembly comptera trois parties, correspondant aux trois constituants cls de notre archive cible. Ce chier est structur par un schma XML qui nous aidera viter les erreurs de syntaxe. Len-tte du chier 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 chier 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 chiers identis dans un rpertoire prdni. La dernire va parcourir tous les modules du projet et en extraire le code source. Le Listing 13.5 montre ce chier 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

Encore plus loin avec Maven

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 chier 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 suft de lancer la commande mvn assembly:assembly. Nous lavons dj vu, cette syntaxe correspond linvocation dune tche spcique dun plugin et non dune phase de construction du projet.

3. http://maven.apache.org/plugins/maven-assembly-plugin/.

Chapitre 13

Respecter un format de distribution

219

Cependant, ce plugin va provoquer lexcution de la phase package du projet (et de tous ses modules). Cest au cours de cette excution quil dcouvrira les constituants de chaque projet et identiera les rpertoires de code source (y compris le code gnr) et les binaires produits. Lintgration continue produit notre livrable Notre serveur dintgration continue produit dj, intervalles rguliers, nos binaires, prts tre tests au-del de ce que nos tests automatiss savent contrler. Il serait dommage de ne pas lui demander de produire aussi notre livrable, ne serait-ce que pour nous donner un moyen de vrier le respect de son format. Lide parat bonne, mais quelle cible Maven invoquer ? Devons-nous remplacer le mvn install par le fameux assembly:assembly. Nous voudrions que la production de ce tar.gz soit mieux intgre dans la construction du projet, quelle soit le rsultat de sa construction par dfaut. Le plugin assembly a la bonne ide de proposer une autre tche, laquelle est prvue pour sexcuter au sein dun cycle de construction du projet. la diffrence du assembly:assembly, nous pouvons associer assembly:single une phase du projet, et il sera invoqu automatiquement lors de sa construction. Le Listing 13.6 indique la conguration que nous appliquons.
Listing 13.6 : Invocation du assembly:single au cours de la construction du projet
<plugins> <plugin> <artifactId>maven-assembly-plugin</artifactId> <version>2.2-beta-4</version> <inherited>false</inherited> <configuration> <descriptors> <descriptor>src/assembly/livrable.xml</descriptor> </descriptors> </configuration> <executions> <execution> <goals> <goal>single</goal> </goals> <phase>install</phase> </execution> </executions> </plugin> </plugins>

Solution miracle ? Eh bien non, chec cuisant. Le plugin assembly plante lamentablement en indiquant quil ne trouve pas notre EAR :(.

220

Encore plus loin avec Maven

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 chier POM sert dclarer nos modules et de parent commun pour mutualiser la conguration 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 ls puissent tre construits. Cela signie 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 chier racine pom.xml un second chier POM : pom-assembly.xml. Dans ce nouveau descripteur Maven, nous plaons la conguration du plugin assembly, ainsi que la dclaration dun unique module qui pointe vers le pom initial. Le Listing 13.7 montre ce nouveau chier, 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

Respecter un format de distribution

221

... ) </plugin> </plugins>

</build> </project>

En lanant Maven avec loption -f, nous pouvons indiquer le chier 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 conits qui en rsultent, mais via le chier 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

Encore plus loin avec Maven

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 m

Clairement identi. Test de manire unitaire, fonctionnelle, mais aussi en charge et/ou en endurance selon les mcanismes de test et nos contraintes. Contrairement une ide trop rpandue, les outils ne sont pas le facteur limitant dans ce domaine. Respectant nos critres qualit et rgles de codage, dont les mtriques sont historises. Fournissant toutes les indications ncessaires pour tracer son origine. Mis disposition de tous les dveloppeurs qui veulent le tester ou bncier des dernires corrections. Prt pour une utilisation directe par les quipes de production.

m m

Le chemin a t long depuis notre petit projet rigolo chang par e-mail, et loutillage a largement progress. Si la taille de nos chiers 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 abilit 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 cone 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 sufra probablement pas faire des miracles si on vous vend les mthodes agiles sur ce seul critre, mez-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

Encore plus loin avec Maven

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 protant 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 conits : 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 ofcielle et nance 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 prcongurer 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

Un nouveau projet dmarre

225

Listing 14.1 : Un POM dentreprise pour Geegol


<project 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/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.geegol</groupId> <artifactId>geegol</artifactId> <name>Geegol corporate POM</name> <version>1</version> <packaging>pom</packaging> <!-- informations lies l'infrastructure rseau de l'entreprise --> <ciManagement> <system>hudson</system> <url>http://hudson.geegol.com/</url> </ciManagement> <scm> <connection>scm:svn:http://svn.geegol.com/trunk</connection> <developerConnection>scm:svn:https://svn.geegol.com/trunk</ developerConnection> <url>http://fisheye.geegol.com/</url> </scm> <repositories> <repository> <id>geegol.snapshots</id> <url>http://nexus.geegol.com/content/groups/public-snapshots/</url> <snapshots> <enabled>true</enabled> </snapshots> </repository> </repositories> </project>

Ce POM commun simplie un peu la dnition des projets dvelopps au sein de lentreprise, mais ne fait quefeurer la question. Commencer un projet sur cette seule base ne va pas aider beaucoup lquipe de dveloppement pour un dmarrage sur les chapeaux de roue. Copier-coller Autre option, qui vient lesprit de tout le monde : le bon vieux copier-coller. La copie est une opration de base en informatique, peut-tre la plus utilise mais aussi la plus dnigre par les architectes : dans une copie, il y a toujours un lment de trop !

226

Encore plus loin avec Maven

Partie III

Selon cette approche, Raphal commence par reproduire la structure de base de notre projet et par copier nos chiers 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 identie 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 chiers 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] task-segment: [archetype:generate] (aggregator-style) [INFO] -----------------------------------------------------------------------[INFO] Preparing archetype:generate [INFO] No goals needed for project - skipping [INFO] [archetype:generate {execution: default-cli}]

Chapitre 14

Un nouveau projet dmarre

227

[INFO] Generating project in Interactive mode [INFO] No archetype defined. Using maven-archetype-quickstart (org.apache.maven. archetypes:maven-archetype-quickstart:1.0) Choose archetype: 1: local -> maven-archetype-echo-mojo (Un plugin Maven "hello world") (...) 42: internal -> gmaven-archetype-mojo (Groovy mojo archetype) Choose a number: (1/2/3/4/5/6/7/8/9/10/11/12/13/14/15/16/17/18/19/20/21/22/23/2 4/25/26/27/28/29/30/31/32/33/34/35/36/37/38/39/40/41/42) 16: : 1 [INFO] artifact org.apache.maven.archetypes:maven-archetype-mojo: checking for updates from central Define value for groupId: : com.geegol.maven.plugins Define value for artifactId: : demo-maven-plugin Define value for version: 1.0-SNAPSHOT: : Define value for package: com.geegol.maven.plugins: : Confirm properties configuration: groupId: com.geegol.maven.plugins artifactId: demo-maven-plugin version: 1.0-SNAPSHOT package: com.geegol.maven.plugins Y: : Y [INFO] --------------------------------------------------------------------------[INFO] Using following parameters for creating OldArchetype: maven-archetype-moj o:RELEASE [INFO] --------------------------------------------------------------------------[INFO] Parameter: groupId, Value: com.geegol.maven.plugins [INFO] Parameter: packageName, Value: com.geegol.maven.plugins [INFO] Parameter: package, Value: com.geegol.maven.plugins [INFO] Parameter: artifactId, Value: echo-maven-plugin [INFO] Parameter: basedir, Value: D:\ [INFO] Parameter: version, Value: 1.0-SNAPSHOT [INFO] ********************* End of debug info from resources from generated POM *********************** [WARNING] org.apache.velocity.runtime.exception.ReferenceException: reference : template = archetype-resources/src/main/java/EchoMojo.java [line 38,column 31] : $ {project.build.directory} is not a valid reference. [INFO] OldArchetype created in dir: D:\demo-maven-plugin [INFO] -----------------------------------------------------------------------[INFO] BUILD SUCCESSFUL [INFO] ------------------------------------------------------------------------

Listing 14.3 : Structure de fichiers gnre


D:\demo-maven-plugin>dir Rpertoire de D:\demo-maven-plugin 04/09/2009 04/09/2009 04/09/2009 04/09/2009 08:55 08:55 08:55 08:55 <REP> <REP> <REP> . .. 845 pom.xml src

228

Encore plus loin avec Maven

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 nal 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 chiers 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

Un nouveau projet dmarre

229

Sauf si lon consulte la description du plugin archetype, et en particulier sa tche create-from-project. Comme son nom le suggre, celle-ci propose de construire un archtype partir dun projet normal, pas ncessairement conu pour servir darchtype. En quelque sorte, il sagit dune rtro-ingnierie qui va extraire un modle partir dune implmentation concrte. La version 1.2.6 de noubliepaslalistedescourses est particulirement russie. Aprs cinq versions correctives, le code est trs stable, et nous sommes trs conants sur la bonne intgration de tous les outils mis en uvre. Pour construire un archtype sur cette base, il nous suft de partir de son code source et de lancer la commande magique. Celle-ci va identier dans tous nos chiers de conguration et nos sources lutilisation du nom de package fr.noubliepaslalistedescourses et assembler un archtype bas sur tous nos chiers dspcialiss du nom de notre projet. Larchtype est prt en quelques minutes dans le rpertoire target/generatedsources/archetype (il est sous sa forme de projet Maven ; il nous suft de lancer, depuis cet emplacement, un trs classique mvn install pour le convertir en binaire utilisable) ! Raphal na plus qu lancer la commande complmentaire : mvn archetype:generate, en prcisant largument -Dcatalog=local signalant quil veut utiliser ses propres archtypes, prsents sur son poste de dveloppement, et pas ceux mis disposition par la communaut Maven. Quelques instants plus tard, le projet malistedecadeauxpournoel est prt pour tre enregistr dans son propre gestionnaire de sources Subversion, avec un code fonctionnel quil ne restera plus qu adapter aux besoins spciques du nouveau projet.

Grer un projet de rfrence


Nous avons donc trouv une solution trs lgante pour repartir dun projet existant dont nous apprcions les qualits pour lancer une nouvelle production. malistedecadeauxpournol protera ainsi des longues heures de mise au point et de lexprience acquise sur le projet qui la prcd. Dans de nombreux cas cependant, cest linfrastructure du projet aussi bien sa conguration Maven que les nombreux frameworks utiliss qui est intressante pour le nouveau dveloppement, les aspects fonctionnels tant probablement assez loigns. Au mieux, quelques classes utilitaires seront reprendre, mais certainement pas les centaines de classes que nous avons accumules depuis le dbut du projet.

230

Encore plus loin avec Maven

Partie III

Donner le meilleur de nous-mmes Le mcanisme extrmement simple qui permet de crer un archtype encourage une pratique simple : dvelopper un projet de rfrence, une application blanche, dans laquelle nous mettrons en place toute notre expertise. Cette application utilisera une slection de frameworks correspondant ltat de lart, avec une prconguration claire et largement documente. Vous avez probablement dj vu ces chiers de proprits sufxs -sample qui contiennent nettement plus de commentaires explicatifs que de valeurs de conguration. Pour notre application blanche, nous mettons un point dhonneur ce que chaque chier de conguration, classe ou POM prsente une explication dtaille de ce quil ralise, pourquoi et comment. Nous accompagnons chaque framework dune classe dexemple, qui sert de point de dpart tout dveloppeur novice qui le connatrait mal, an de le mettre sur la bonne piste. Le dveloppement se faisant beaucoup par imitation, les premires lignes de code disponibles sur le projet sont capitales. Dmarrer sur les bons rails Utilise comme archtype, notre application blanche met la disposition des projets venir un ensemble cohrent, nement outill et document, qui pourra tre, par la suite, adapt des besoins spciques, mais partir dune base valide. tant elle-mme un projet Maven part entire, notre application blanche peut bncier de loutillage dintgration continue pour valider son niveau de qualit et sa stabilit. Son dveloppement et son volution sont donc assez simples. Si un projet qui la utilise comme archtype a expriment avec succs une nouvelle technologie, il lui suft de proposer lvolution associe. Notre outillage de contrle qualit faisant le reste pour assurer la cohrence de lensemble. Sbastien passe nous voir, en esprant cette fois ne pas nous trouver au milieu dune bataille de chiffonniers (voir le Chapitre 9). Il vient nous demander conseil pour lancer une petite application exprimentale. Il ne veut pas sembarquer dans une tude darchitecture pour si peu mais simplement partir sur les bons outils du moment, si possible avec quelques pistes pour ne pas perdre de temps. Voil qui ne pouvait pas mieux tomber ! Notre application blanche est encore ltat dbauche, et nous y avons transfr quelques morceaux choisis de noubliepaslalistedescourses, en constatant au passage que nous aurions pu faire un petit effort en termes de commentaires pour rendre ses aspects techniques plus comprhensibles. Un rapide archetype:create-from-projet suivi de son petit frre archetype:generate et Sbastien peut repartir avec un socle encore trs imparfait mais dj bien plus

Chapitre 14

Un nouveau projet dmarre

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 nal par une petite guerre dinuence 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

Encore plus loin avec Maven

Partie III

Comment construire lapplication avec le mme outillage et les mmes commandes ? Comment intgrer cette technologie avec notre infrastructure mtier base sur Spring ? Lapplication blanche met ds le dbut ces questions sur le tapis, y rpondre au plus tt permettra dintroduire Flex sur un nouveau projet sans buter sur ces problmes. Un support de dmonstration Pour ceux qui nont aucune prfrence, lapplication blanche lance en mode dmonstration permet de se faire une ide du rsultat obtenu pour un code source donn, et donc de discuter sur un exemple concret pour prendre une dcision raisonne. Elle peut galement servir de support de formation. Jrme veut dmarrer un projet fond sur Struts 2 et Spring, et former dans le mme temps les dveloppeurs novices ces technologies. Pour les sessions de formation quil va animer, il pourrait partir des projets dexemple qui accompagnent ces deux frameworks et donner les pistes pour que chacun fasse le lien avec lapplication dvelopper. Aprs tout, ces exemples sont conus pour cela et en principe taills pour mettre en valeur les bonnes pratiques. Cependant, ils ne collent pas exactement la ralit de lapplication et des nombreux outils quelle intgre. Spring propose par exemple de nombreux mcanismes de conguration, alors que nous nen exploitons quun seul le but nest pas de former des experts en Spring, mais des dveloppeurs conants et guids dans leur travail. Jrme prfre donc partir de notre application blanche, y ajouter la conguration et une slection dexemples adquats. Il cre ensuite un archtype. Chaque junior qui participe la formation va alors gnrer, partir de larchtype, sa propre application de dmonstration/exprimentation et se lancer dans ses premires lignes de code sur cette base. Les classes de lapplication blanche donneront lassise de nos exercices de formation, et les exemples permettront dexpliquer les mcanismes en jeu. Au terme de la formation, lorsquils commenceront travailler sur le projet, nos dveloppeurs tout juste forms ne seront pas dboussols de retrouver la mme structure de projet et gagneront ainsi en efcacit.
INFO Bien que les archtypes soient un moyen rapide de rutiliser une application existante, et donc un encouragement dnir des applications blanches, celles-ci prsentent quelques cueils : La maintenance. Cela revient vite cher faire vivre. La cohrence. Cela devient vite un fourre-tout dans lequel on dverse tout ce qui trane.

Chapitre 14

Un nouveau projet dmarre

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 ables, mal documents ou dont lavenir est incertain. nous de nous montrer convaincants

236

Encore plus loin avec Maven

Partie III

Les limites
Fabrice prend les devants et expose dofce 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 congurer un gros plugin comme Cargo (voir Chapitre 8). Quest-ce qui empche de modier ce format POM pour le rendre plus compact, ou lui ajouter des fonctionnalits ? Le code qui analyse ces chiers 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 difcult 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, an 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

Avons-nous fait le bon choix ?

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 prol, dans le chier 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 able doit tre totalement reproductible. La liste est encore longue des fonctionnalits manquantes, mal chues, 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 conits nest pas exactement quivalent ? Les plugins Olivier signale galement la difcult pour identier un plugin qui rponde un besoin prcis et pour en qualier 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 modiant sa conguration). Le projet Apache Maven nhberge ofciellement 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 nalement llment principal manipul par lutilisateur nal, 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

Encore plus loin avec Maven

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 ofcielle 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 ofcielles 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 bnciera 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 rexes, 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

Avons-nous fait le bon choix ?

239

Le support de Maven est centralis sur une liste de diffusion (users@maven.apache.org) qui runit ses utilisateurs et une majorit de ses dveloppeurs. Les messages y sont nombreux, touchent tous les sujets, et les rponses viennent rapidement en raison du grand nombre dutilisateurs en ligne. Il ny a cependant aucune obligation de rsultat et aucun moyen daccentuer lappel au secours, sauf relancer sa question au risque de se faire rejeter plutt quaider par les membres bnvoles. Si vous faites appel la communaut, pensez poser des questions prcises en dtaillant clairement votre besoin, votre environnement (vous pouvez toujours lire ce petit guide1), et nhsitez pas rpondre aux autres utilisateurs : nous avons tous commenc de cette faon et cest ainsi quon apprend le mieux utiliser Maven. La liste des utilisateurs de Maven a dpass la taille critique et sautoalimente : les utilisateurs avertis aident les novices. Lquipe des dveloppeurs na plus besoin dassurer elle-mme le support de premier niveau et peut donc se concentrer sur les dveloppements et les corrections. Vous pouvez aussi retrouver une partie des dveloppeurs du projet ainsi que des utilisateurs sur lIRC2 (serveur irc.codehaus.org, canal : #maven). Ce mdia a lavantage dtre en direct et peut donc vous apporter des rponses plus rapidement que la liste de diffusion, si vous avez la chance de tomber sur les bons interlocuteurs. Par contre, contrairement cette dernire, comme il nest pas possible daccder aux discussions qui ont eu lieu pendant une dconnexion, nesprez pas quune personne vous rponde si elle ntait pas l au moment o vous avez pos votre question. Enn, noubliez pas quil y a beaucoup de personnes dans lquipe Maven qui ne sont pas sur le mme fuseau horaire que nous. Nesprez pas contacter les membres outre-Atlantique le matin heure franaise. Seule contrainte : tous ces changes se font en anglais, parfois avec une syntaxe qui doit dsesprer ceux dont cest la langue maternelle. Heureusement, les francophones sont rputs pour leur comptence en langues trangres ;). Si, malgr tout, ce nest pas votre cas, le site developpez.com hberge un forum francophone consacr Maven 3, ainsi quune FAQ4 bien remplie.

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

Encore plus loin avec Maven

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 denitive 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 spciques 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, bnque 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 justications 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

Avons-nous fait le bon choix ?

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 spciques 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 "spciques". 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-spcique, les artefacts construits si, au nal, ils sont des archives JAR sont composs dlments peu courants. La conguration ncessaire dans Maven pour obtenir un rsultat convaincant serait signicative. 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 rafnements dont la compatibilit OSGi, il faut bien reconnatre que Maven se serait assez mal prt au jeu. Enn, 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 chier 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.

Comme quoi, lide fait tout de mme son chemin


6. https://src.springframework.org/svn/spring-framework/trunk/build-spring-framework/ pom.xml.

242

Encore plus loin avec Maven

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 simplier 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 conguration 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 conguration, 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

Avons-nous fait le bon choix ?

243

crer un Domain Specic Language, un langage de programmation ddi une tche particulire : la construction de projet. Lintgration dIvy dans Gradle se fait via ce DSL plutt que par les tches Ant Ivy, ce qui simplie sa manipulation. Gradle dnit galement la notion de plugin, sans rapport avec la signication de ce terme dans Maven. Un plugin Gradle est plutt un ensemble de tches Gradle runies et rutilisables sur plusieurs projets. Le Listing 15.1 donne un exemple de script Gradle. La syntaxe est particulirement compacte.
Listing 15.1 : Un script simple de build Gradle
usePlugin java sourceCompatibility = 1.5 version = 1.0 manifest.mainAttributes( Implementation-Title: Gradle Quickstart, Implementation-Version: version ) repositories { mavenCentral() } dependencies { compile group: commons-collections, name: commons-collections, version: 3.2 testCompile group: junit, name: junit, version: 4.+ } test { options.systemProperties[property] = value } uploadArchives { repositories { flatDir(dirs: file(repos)) } }

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

Encore plus loin avec Maven

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 chiers 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 complexier 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

Avons-nous fait le bon choix ?

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 nira 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 Trac de la liste users@maven.apache.org.

Autre indicateur, le trac sur le site web maven.apache.org. Les Figures 15.2 et 15.3 afchent le compte rendu des visites pendant un mois, ce qui donne une bonne ide du nombre dutilisateurs de Maven amens congurer 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

Encore plus loin avec Maven

Partie III

Figure 15.2 Origine gographique des visiteurs de maven.apache.org.

Figure 15.3 Trac sur le site web maven.apache.org.

Figure 15.4 Tlchargements mensuels de Maven sur un an, toutes versions confondues.

Chapitre 15

Avons-nous fait le bon choix ?

247

Lquipe de dveloppement Arnaud poursuit en prsentant le cur du projet Apache Maven, ceux qui le dveloppement et dont nous dpendons au nal. 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 Denitive 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 congur. 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 celles 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

Encore plus loin avec Maven

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 let, reposant sur les paules de quelques personnes, il apprcie davoir enn 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 bncie 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 2.x poursuit le dveloppement du Maven que vous utilisez peut-tre dj et dont nous avons parl au l des paragraphes qui prcdent. Des volutions et des corrections successives lui sont apportes pour largir ses fonctionnalits et ladapter de nouveaux besoins. Maven 3 a longtemps t appel Maven 2.1, mais son dveloppement prend nettement plus de temps que prvu et les changements internes sont sufsamment radicaux pour justier 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

Avons-nous fait le bon choix ?

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 proter de cet lan. Les nouvelles fonctionnalits quil apporte peuvent sembler supercielles mais limportance est avant tout le redmarrage de cette branche de dveloppement en parallle de Maven 3. Maven 2.1 introduit :
m

La possibilit de scuriser les mots de passe dnis dans le chier settings.xml de lutilisateur, et donc un peu trop ouvertement exposs aux regards indiscrets. Ceux-ci peuvent dsormais tre chiffrs et la cl stocke, par exemple, sur une cl USB et donc inexploitable en labsence de son utilisateur lgitime (pensez au cas de vol de lordinateur portable dun dveloppeur Maven, un quidam pourrait venir lenrichir et le corriger nos dpens ). Le tlchargement des dpendances en parallle. Cela na pas un grand intrt pour le dveloppeur qui ne va tlcharger ses dpendances quune seule fois quoique, lors de la premire utilisation, quand Maven "tlcharge la moiti dInternet", cela puisse se sentir. Sur un serveur dintgration continue, par contre, si on dsire utiliser un dpt local vierge avant chaque construction pour faire les choses bien proprement, le gain de temps peut tre signicatif. La construction multimodule par morceaux. Il est possible de demander Maven 2.1 de ne construire que certains modules du projet, et ventuellement tous les modules dont il dpend ou encore tous les modules qui dpendent de lui. Cette fonctionnalit tait dj prsente sous forme dun plugin ddi reactor, elle est dsormais disponible au cur de Maven. Sans oublier une nette amlioration des performances sur linitialisation de Maven dans un contexte avec de nombreux modules.

250

Encore plus loin avec Maven

Partie III

Maven 2.2

Deuxime de la ligne, Maven 2.2 est apte :


m

Remplacer la couche daccs rseau HTTP jusquici prise en charge par un composant spcique Maven par le composant trs rput Apache HTTPClient. Laccs aux dpts dartefacts selon les protocoles HTTP, HTTPS ou WebDav utilise dsormais cette bibliothque. Corriger plusieurs bogues, dont un li la manipulation des ${variables} lorsque le POM est install dans le dpt local ou dploy. Cette fonctionnalit introduite dans Maven 2.1.0 a entran des rgressions sur certains plugins, notamment celui de signature GPG ? elle a donc t retire au prot dune gestion plus stricte. Apporter quelques amliorations mineures.

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 dni lheure o nous rdigeons ces lignes, mais limportant est quune dynamique soit enn en place pour avoir rgulirement de nouvelles versions de Maven 2 et redynamiser les dveloppements.

On peut cependant donner quelques lments sur ce qui pourrait apparatre dans les prochaines versions de Maven 2.x :
m

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 ; la gestion simplie et amliore des projets multimodules, en termes de plugins sexcutant de manire globale ( aggregator), de gestion globale de la version du projet ou de bonne tanchit entre les divers plugins utiliss par chaque module ;

Chapitre 15

Avons-nous fait le bon choix ?

251

lintgration autant que possible des volutions en cours de dveloppement dans Maven 3 et, en particulier, progressivement celle de la bibliothque Mercury (voir plus loin) ; et, bien sr, la correction de nombreux bogues.

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.

La seconde difcult dans le dveloppement de Maven 3 touche la prennit des API internes de Maven, utilises par certains plugins, et que lquipe de dveloppement voudrait pouvoir retravailler. La limite entre public et interne dans Maven 2 est en effet assez oue, et pour traiter certains besoins particuliers, les dveloppeurs de plugins ont parfois fait appel du code assez profond de Maven 2. Maven 3 nest donc pas encore disponible, mme si les premiers essais sont encourageants. Vous lutilisez dailleurs dj sans le savoir travers son intgration dans votre IDE, Maven 3 tant la seule version qui se prte ce jeu. Son dveloppement complet devrait prendre encore au moins un an, le temps de le stabiliser parfaitement et denrichir encore les tests dintgration pour une conance renforce. Maven 3 est donc lavenir, mais pas celui de demain matin. Son dveloppement bncie de toute lattention et de la comptence de Sonatype, qui y affecte plusieurs personnes temps plein. Celles-ci ne veulent cependant pas brler les tapes et comptent bien attendre davoir une solution conforme leurs exigences et solidement btie pour pouvoir affronter les annes venir. Le reste de lquipe attend patiemment que le gros

252

Encore plus loin avec Maven

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 chier 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 modication. 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 identis 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

Avons-nous fait le bon choix ?

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 prot 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 dnition des versions et la gestion des conits. Laccs aux dpts a t rcrit par lquipe du moteur de servlet Jetty, vritables experts du protocole HTTP. La rsolution des conits 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

Encore plus loin avec Maven

Partie III

La faon dont le modle du projet (le fameux POM) est construit partir des chiers 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 modications. La tentative dune version 2.0.11 y a en particulier laiss des plumes. Cette gestion clarie 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 conguration 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.

Le format du chier POM tant dsormais libr, il sera possible dutiliser dautres langages que XML comme Groovy, Python, Ruby ou Yaml pour exprimer les mmes mtadonnes. La lecture du chier POM sera paramtrable dans Maven 3.1, ce qui permet dintroduire des formats alternatifs, voire de construire des outils manipulant les mtadonnes Maven dans dautres langages que Java. Reste cependant dterminer clairement comment ces diffrents formats seront publis sur les dpts dartefacts pour tre toujours lisibles par dautres utilisateurs de Maven. Attention, travaux en cours !
Listing 15.1 : Un POM Maven 3 bas sur les attributs XML
<project xmlns="http://maven.apache.org/POM/4.1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.1.0 http://maven.apache.org/maven-v4.1.0.xsd"> <modelVersion>4.1.0</modelVersion> <parent groupId="fr.noubliepaslalistedescourses.parent" artifactId="noubliepaslalistedescourses-parent" version="2"/> <name>noubliepaslalistedescourses :: modele metier</name> <artifactId>noubliepaslalistedescourses-model</artifactId> <packaging>jar</packaging> <version>1.1-SNAPSHOT</version> <dependencies> <dependency groupId="log4j" artifactId="log4j" version="1.2.14"/>

Chapitre 15

Avons-nous fait le bon choix ?

255

<dependency groupId="junit" artifactId="junit" version="4.5" scope="test"/> <dependency groupId="org.easymock" artifactId="easymock" version="2.5.1" scope="test"/> </dependencies> <build> <plugins> <plugin groupId="org.apache.maven.plugins" artifactId="maven-compiler-plugin" version="2.0.2"> <configuration> <source>1.5</source> <target>1.5</target> </configuration> </plugin> <plugin groupId="org.apache.maven.plugins" artifactId="maven-surefire-plugin" version="2.2"/> </plugins> </build> </project>

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 ofcielle de Maven 3 prendra cependant plus de temps an de peauner chaque dtail. Cinq personnes travaillent plein-temps sur Maven 3, aussi les choses avancent grands pas, mais nesprez pas lannonce ofcielle dun Maven 3.0.0 General Availability avant n 2010.

qui appartient Maven ?


Le comit est presque convaincu mais il a tout de mme quelques rticences. Loutil semble bon, promis un bel avenir, mais dans les mains de qui mettons-nous lavenir de ce qui est en train de devenir le projet no 1 de Geegol ?

256

Encore plus loin avec Maven

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 nale ne soit pas le reet dun compromis accept par tous. Maven sest dvelopp dans cet esprit, chaque grande dcision tant soumise la communaut des dveloppeurs et retant 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

Avons-nous fait le bon choix ?

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 spciques 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 difcile 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 Denitive 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 difcult 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

Encore plus loin avec Maven

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 nancier ne suft 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 nanciers. 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 nance lhbergement dune partie de linfrastructure de dveloppement en particulier, le dpt dartefacts central et les gigaoctets de trac 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

Avons-nous fait le bon choix ?

259

La garantie par lopen-source Si Sonatype se comporte aujourdhui comme un exemple dans sa dmarche de contribution lopen-source, quen sera-t-il lavenir ? Que deviendrait Maven si cette socit venait tre rachete par un groupe aux intentions plus lucratives ? Aprs tout, en moins dun an, nous avons vu Oracle racheter Bea puis SUN pendant que VMware rachetait SpringSource. Quen pensent ceux qui ont mis sur la machine virtuelle Java alternative JRockit et qui ne peuvent mme plus la tlcharger sans passer par le service de support dOracle ? Ne perdons pas de vue deux lments cls :
m

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 signicative, le prix qui en serait demand serait peut-tre justi. Dans le cas contraire, la version libre restera libre et pourra tenter de dvelopper les mmes services, voire mieux, ce qui sest dj vu. Le dveloppement de Maven est port par ses dveloppeurs. Le droit modier le code source de Maven est attribu des personnes reconnues pour la qualit de leur contribution la communaut et pour leur capacit travailler selon un modle communautaire. En aucun cas, une socit ne peut prtendre possder Maven ou son quipe de dveloppement ( moins de tous les embaucher). Des dveloppeurs open-source qui verraient leur socit prendre une position trop lucrative ne manqueraient pas daller voir ailleurs, emportant avec eux la cl daccs au SVN de Maven. Sauf crise grave sur le march de lemploi en informatique, il restera toujours des dveloppeurs indpendants ou raisonnablement lis leur socit pour faire de Maven un projet libre. 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 qualie de fork. Il sagit cependant dune situation rare, une sorte de solution de la dernire chance lorsque des conits 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

Encore plus loin avec Maven

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 modie pas la lgre. Lavenir de Maven est encore ou, 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 exibilit, 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 proter 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 efcace. 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 an dviter les cueils que nous avons dj pu rencontrer.

Les bonnes bases


Bienvenue pour cette session de formation Maven 101 essentials. Lobjectif de cette formation nest pas de vous transformer en gurus de Maven, connaissant la moindre de ses celles. Honntement, a ne vous apporterait pas grand-chose. Ce que nous voulons, cest faire de vous des dveloppeurs efcaces, laise avec cet outil que vous allez utiliser au quotidien. Nous voulons surtout vous empcher de partir sur de mauvaises pistes et de nir, dans quelque temps, par regretter davoir choisi Maven. Au contraire, nous allons vous donner les cls pour en faire un alli de poids dans vos dveloppements et dans lindustrialisation de votre travail dingnierie.

262

Encore plus loin avec Maven

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 cels 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 recongurer 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 congurant 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 m m

de simplier de lutilisation de Maven ; de simplier lintgration de nouveaux dveloppeurs ; dviter de tomber dans des problmes ou des bogues qui font perdre un temps prcieux.

Commandement no 2 : Simplicit tu choisiras. Notre premier mauvais lve est un projet que nous avons voulu faire migrer dAnt vers Maven. Les technologies en uvre avaient toutes le plugin Maven adquat, mais la structure initiale du projet tait particulirement htroclite. Notre erreur a t de vouloir la conserver telle quelle, ce qui imposait :

Chapitre 16

Nos recommandations

263

m m m m

plusieurs tapes de compilation entre divers rpertoires de sources interdpendants ; plusieurs phases dinstrumentation du code ; une excution spare pour le calcul du taux de couverture des tests ; un assemblage de multiples sous-versions du mme projet, incluant diverses options et le code optionnel associ.

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 bnce. 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 efcace.
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

Encore plus loin avec Maven

Partie III

Commandement no 3 : Au fur et mesure de tes besoins, les outils ncessaires tu mettras en place. La plthore de plugins danalyse de code disponibles nous encourage mettre en place un suivi qualit de haut niveau. Il est si simple de lancer lun de ces nombreux outils pour analyser le code et identier des problmes automatiquement il est juste dommage quil ne les corrige pas aussi automatiquement ! Nous avons ainsi pris un projet rcemment adapt Maven et produit quelques mgaoctets de rapports varis. Mais que faire de ces pages et des indicateurs en tout genre que nous obtenons ? Comment traiter des rgles parfois incompatibles ou, en tout cas, dont nous ne voyons pas forcment lintrt ? Si nous utilisons les rgles par dfaut de Checkstyle, tablies sur les recommandations de codage SUN qui datent des dbuts de Java , celui-ci nous insultera pour chaque mthode qui ne dispose pas de commentaire Javadoc. Issue dune poque rvolue, cette rgle part du principe que tout code public doit tre accompagn dun commentaire explicatif. Elle va nous amener crire ce genre de chose :
/** * affecte le prenom * @param prenom le nouveau prenom */ public void setPrenom( String prenom ) { ...

Voil un magnique commentaire dont lutilit est sans appel ! Soit vous gnrez lensemble des commentaires pour satisfaire Checkstyle, soit vous dnissez 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

Plutt quune mthode quivalente utilisant un vocabulaire obscur, mais largement accompagne de commentaires et qui satisfait nos outils danalyse :
/** * Rsiliation du contrat * @param l lidentifiant de contrat * ... */ resCtr( long l ) throws ResErrorException

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 n en soi. Ce doit tre laboutissement dune dmarche qui dnit les rgles que nous voulons vrier 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 n, juste parce que le format du chier 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 modication 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 lidentication 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 sufsamment 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

Encore plus loin avec Maven

Partie III

sur des technologies diffrentes et dont nous voulons clairement scinder la gestion. Si la dcomposition en modules ns 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 an 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 justier 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 n 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 gurer :
m m m m m m m m

Maven, le programme en tant que tel mais aussi tous les plugins quil utilise ; le gestionnaire de versions de sources (Subversion, Git) ; le gestionnaire de tches et de bogues (Jira, Mantis) ; le repo (nexus, artifactory, archiva) ; le serveur dintgration continue (Hudson, Continuum, Bamboo) ; les outils de tests (Selenium, Fitnesse) ; lenvironnement de dveloppement intgr (Eclipse, NetBeans, Intellij) ; et bien dautres encore.

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 afcher les lignes modies 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 uniant 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 nalement 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 protait 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 ger 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 dnir 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

Encore plus loin avec Maven

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 dnir une conguration centralise, mais qui ne sera applique que sur les modules qui utilisent le plugin.
INFO Les plugins dclars pour le reporting ne protent 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 modier 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.

Commandement no 8 : Comme la peste les dpendances optionnelles tu viteras. Nous avons cr une belle bibliothque utilitaire commons-geegol dont lobjectif est dapporter tous nos projets des classes utilitaires, facilitant laccs de nombreux outils. Ce code dpend donc de trs nombreuses dpendances, mais seule une souspartie est utile pour un utilisateur, qui ne va exploiter que quelques classes de notre bibliothque. Nous pouvons :
m

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 congurer 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 nal. Par contre, nous gagnerons dans la nesse 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 m

Attendre la compilation moins dune seconde cest fantastique, mais rarissime. 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 suft 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 modication 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

Encore plus loin avec Maven

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 proter pour dsactiver les tapes non indispensables de la construction du projet. Le Listing 16.1 montre lactivation dun prol 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 conguration pour associer le plugin adapt la phase de recopie des chiers 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 congurateur 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 reter 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 nal, 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

Encore plus loin avec Maven

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 enn 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 conguration 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 ofciel 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 chier .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 n
Pour conclure, sachez que le Denitive 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 suft de lancer la commande universelle mvn install !

Qui est qui ?


Vous vous demandez qui sont ces personnages qui peuplent les pages de ce livre ? Les membres francophones de lquipe Maven Lorsque nous avons dcid de romancer notre ouvrage, nous nous sommes pos la question de savoir qui seraient les personnages qui allaient nous entourer dans notre aventure. La rponse fut vite trouve. Quoi de mieux que de rendre hommage notre faon aux membres francophones de lquipe de dveloppement du projet Maven ?
1. http://www.sonatype.com/products/maven/documentation/book-defguide.

276

Encore plus loin avec Maven

Partie III

Laissons-les se prsenter (par ordre alphabtique du prnom, comme a, pas de jaloux).


Carlos Sanchez Bonjour tous,

Carlos Sanchez, espagnol, 29 ans. Je travaille pour G2iX aprs avoir travaill chez Mergere/DevZuz, la startup qui a donn des services professionnels au-dessus de Maven/Continuum/Archiva. Jai encore pour nos clients beaucoup de travail avec ces produits. Jai commenc avec le projet Maven en 2004, en participant au dveloppement des plugins, du noyau et en grant le repository central. Aprs, jai contribu aux autres projets open-source, Apache Archiva, Continuum et Felix, Spring Security, Eclipse IAM Maintenant, je travaille sur des projets lis au cloud computing et en tirant le plus grand avantage de celui-ci pour le dveloppement logiciel, les tests et les bonnes pratiques. Je suis originaire de La Corogne, Espagne, mais jhabite Los Angeles, Californie, depuis quatre ans. Jai tudi le franais, et je suis all en France de nombreuses fois : Pyrnes, Alpes, Bretagne, Paris. Mais jai beaucoup oubli mon franais en parlant toujours en anglais :(.
Emmanuel Venisse Salut,

Emmanuel Venisse, 35 ans. Je suis free lance depuis 2005, tout dabord pour Mergere/DevZuz avec nos autres amis de la communaut Maven, mais depuis n 2007, pour divers clients avec notamment la mise en place denvironnement de build (Maven/Continuum/Archiva) et de larchitecture logicielle. Je suis committer sur Maven depuis les premires bta en 2002 (merci Vincent Massol de mavoir prsent Maven cette poque), mais galement Continuum et Archiva. Malheureusement avec de moins en moins de temps disponible maintenant :-(. Dans le pass, jai travaill dans la mme SSII que Nicolas, mais Paris o javais introduit galement Maven ;-).
Fabrice Bellingard Hey !

Fabrice Bellingard, parisien. Entre le dbut de lcriture du livre et sa sortie, jai nalement dcid de passer les 30 ans Gloups ;-) Je suis tomb dans lopen-source

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 nalement devenu committer en 2005. Puis vint Archiva en 2008 (committer et PMC). Depuis n 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 lle, 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 sufsamment conance 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 nalement 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

Encore plus loin avec Maven

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,

Je mappelle Lukas Theussl, 36 ans, autrichien mais actuellement rsidant Copenhague au Danemark. Jai aussi une petite famille, une femme et deux enfants. Ct boulot, je crois que je suis le seul membre non informaticien du PMC Maven, et peut-tre mme parmi tous les committers. Je me suis alors toujours considr comme un outsider. Aprs une thse en physique thorique (spcialit physique nuclaire et particules lmentaires), jai pass plusieurs annes dans des quipes de recherche, en France, en Espagne et au Canada. Actuellement, je ne fais plus la recherche moi-mme, je suis dans ladministration de luniversit de Copenhague et je moccupe de la gestion des divers projets de recherche (europens et internationaux). Comment un physicien est arriv simplanter parmi les dveloppeurs de Maven ? lpoque, on crivait un programme dapplication en physique des particules, et on a dcid dutiliser Maven qui tait assez nouveau ce moment-l. Jai t surtout attir par la possibilit de grer le programme et la documentation (site web, pdf) en mme temps, mais trs vite les divers bogues mont amen corriger Maven lui-mme et soumettre ces patchs, quArnaud avait la volont dappliquer. Le reste, cest lhistoire Jai ensuite aid Arnaud enterrer Maven 1.1, et maintenant je participe surtout au sous-projet Doxia et particulirement la version du plugin pdf pour Maven 2.
Olivier Lamy Bonjour,

Olivier Lamy, bientt 36 ans (une femme et trois enfants). Amateur de bons plats et de bons vins :-). Je suis employ dans un groupe htelier franais (il ny en a pas beaucoup donc vous devriez trouver). Je travaille sur les applications dchanges XML normalis2 avec des partenaires du monde du tourisme et sur la rcriture dapplications client/serveur en web. Jai introduit Maven (en version 0.7 bta pour ce que je me souviens) n 2002 dans mon groupe. Au dbut, dans les projets dont javais la charge mais maintenant je suis en

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 magnique l'est de la Belgique.

Je travaille comme expert technique chez un grand diteur de progiciels nanciers, o je suis responsable de l'volution des frameworks et de l'infrastructure logicielle. Je m'intresse aussi fortement aux techniques et outils de dveloppement, ainsi qu' la qualit logicielle Mon premier contact avec Maven date de 2003, j'ai commenc contribuer au dveloppement de Maven 1 en travaillant sur les plugins lis aux dlivrables J2EE. Je fais partie du Project Management Commitee de Maven depuis 2006, je m'occupe toujours des plugins de packaging, mais galement des aspects de exibilit et de congurabilit d'un projet.
Vincent Massol Bon puisquon dit notre ge je me lance 38 ans :) [le premier qui dit papy se prend une baffe], amateur de tondeuse robot, ne boit pas dalcool, vit la campagne et travaille depuis la maison, du ct de Chantilly avec femme et trois enfants

Neuf ans dopen-source dj : Maven, Cactus, Cargo, MockObjects et autres. Ct Maven, jai rejoint le projet vers 2001-2002 alors quil nexistait que sous la forme dun sous-projet de build du projet Jakarta Turbine. Dabord en tant quutilisateur (jen avais marre de maintenir des dizaines de chiers Ant de mille lignes de long chacun !),

280

Encore plus loin avec Maven

Partie III

puis en tant que committer plus tard an 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 spcique 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 :).

Franais dorigine, je vis actuellement Montral au Canada avec une fabuleuse femme. Sans enfant au dbut de ce livre, me voil pre dun petit garon (le plus beau, bien sr !) sa sortie Avec presque dix ans dexprience en entreprise, je travaille actuellement dans un centre de recherche et ma mission se rsume aider les entreprises dans les mthodologies agiles, la gestion de projet, lassurance qualit, les nouvelles technologies et, bien sr, lopen-source. Concernant Maven, jai commenc utiliser la version 1 vers le milieu 2003, lors dun mandat dans une entreprise de bioinformatique, aprs une implmentation fastidieuse de la fourmi. Ensuite, parcours classique chez ASF : patchs accepts (merci Arnaud !), committer, PMC (merci Brett !), utilisation de Maven dans dautres projets dASF (PMC Shindig), etc. Mon intrt pour Maven se situe principalement dans la gnration de documentation (Doxia avec Lukas !) et les plugins de reporting et de QA.

3. http://xwiki.org.

Chapitre 17

pilogue

281

Les membres de la communaut Java Pour complter notre ne quipe par quelques prols moins "Maven-addicted", nous avons invit quelques-unes de nos connaissances de la communaut Java francophone.
Antonio Goncalves Jai le mme ge que Vincent M. mais tout le monde me donne lge de Fabrice. Le secret de cette fontaine de jouvence ? Maven ! Eh oui, chaque mvn install vous fait gagner du temps, donc, plus je compile avec Maven, plus je rajeunis. Vous avez lu le Portrait de Dorian Gray ? Eh bien, lisez un de mes livres, voire les deux (Java EE 5, aux ditions Eyrolles, et Java EE 6 chez Apress) et vous paratrez plus jeune. Il y a aussi ma lle de quatre ans qui adore Maven en effet, puisque je gagne du temps avec Maven, eh bien jen passe plus jouer avec elle. Vous voyez, Maven, on laime de 7 (4 pour ma lle) 77 ans (si vous connaissez quelquun qui a 77 ans, proposez-lui de dcouvrir Maven, il en sera rjoui).

Consultant indpendant et Java Champion, je suis tantt architecte ou dveloppeur, chez mes clients (de la startup la grande entreprise). Non, non, je ne suis pas chef de projet. Jai dcouvert Java en 1998, puis J2EE en 1999 lorsque je travaillais pour BEA Systems, et jai continu dans la lance de lEnterprise Edition (ou Java EE) jusqu intgrer le JCP en travaillant sur la spcication Java EE 6. Aprs avoir travaill partout dans le monde (enn, trois ou quatre pays), je suis revenu Paris (intra-muros, bien sr), o jai commenc enseigner au Cnam puis cr le Paris Java User Group. Jai crit plusieurs articles, deux livres (je lai dj dit, mais cest pour que vous vous souveniez de les acheter), je parle pas mal aux confrences (je parle beaucoup de manire gnrale) et jadore Maven (a, cest pour Nicolas et Arnaud). Je fais aussi partie de la bande des Cast Codeurs. Quoi ? Vous ne connaissez pas les Cast Codeurs ? Eh bien, retrouvez tout cela sur mon site personnel pour de plus amples informations : http:// www.antoniogoncalves.org.
Franois Le Droff Brestois dorigine, parisien dadoption, jai connu le Minitel mais je suis plus jeune que Vincent M., jai commenc jouer/coder sur le HP 85 de Papa dans les annes 80. Depuis 2007, je suis ingnieur logiciel chez Adobe, aprs neuf ans dexprience dans le dveloppement dapplication Java/JEE chez Schlumberger puis AtosOrigin Open Source Competence Center.

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

Encore plus loin avec Maven

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.

Je fais de lopen-source depuis 2003, en travaillant puis en dirigeant le projet Groovy, le langage dynamique pour la JVM le plus populaire actuellement auprs des dveloppeurs Java, et galement en lanant le framework web Grails. Aprs quelques annes chez des diteurs logiciels et des socits de services, je me suis lanc, jai cr ma bote, G2One, autour des technologies Groovy et Grails, qui a ensuite t rachete par SpringSource, et ce dernier par VMWare un bel exemple de chane alimentaire ou des poupes russes ! Jai beaucoup souffert avec Maven 1, mais je nai pas eu beaucoup loccasion de jouer avec Maven 2, seulement avec le plugin GMaven qui rend Maven un peu plus agrable utiliser mon got ! Mais jespre que ce livre rabibochera les dveloppeurs allergiques Maven avec ce puissant outil de build !
Jrme Van der Linden 27 ans, architecte JEE chez Octo Technology depuis trois ans, o jai rencontr Arnaud et dcouvert Maven (la version 1.0.2 lpoque).

Ni commiter, ni PMC, je suis un simple utilisateur mais fervent dfenseur de loutil. Jai mis en place plusieurs "usines de dveloppement" (intgration continue, tests et bonnes pratiques autour de tout a), dispens des formations chez divers clients, crit quelques articles sur le sujet et surtout jutilise Maven au quotidien ! La version 1 mavait paru intressante compare Ant mais cest surtout la version 2 et toutes ses conventions qui me semblent apporter normment au dveloppement !
Sbastien Le Marchal Breton dorigine, je vis actuellement Casablanca avec ma petite tribu familiale.

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

"Hou l l ! Mais jai plein de tlchargements tranges quand je lance une commande Maven !" "Mais cest quoi ces chiers pom.xml partout dans mon workspace ? En plus, jy comprends rien, moi, ces chiers." "Argh ! Mais ils sont passs o les chiers build ?" "Comment a, on a abandonn Ant ? Mais pourquoi on a abandonn Ant ? Jaimais bien moi Ant et en plus je comprenais !" "Au secours Nico !!!!"
<mode panique: off>

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 enn 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 er 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

Encore plus loin avec Maven

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. Enn, 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 enn, de quoi parlent-ils ?". Il est vrai que linformatique possde un jargon riche, souvent impntrable et anglophone Voici donc notre petit dictionnaire Maven Franais.

Le petit monde open-source


Apache1 La fondation Apache (ASF, Apache Software Foundation) est un organisme amricain but non lucratif qui hberge les infrastructures pour le dveloppement de nombreux logiciels libres, dont le trs clbre serveur HTTP Apache. La fondation encourage la constitution dune communaut pour soutenir un projet donn plutt que les pures qualits techniques de celui-ci, mme si elles font rarement dfaut - des centaines dyeux braqus sur le code sont une bonne garantie de qualit ! Les responsabilits dans un projet Apache sont bases sur le concept de mritocratie : un membre actif, talentueux et respectueux de la diversit de la communaut se verra attribuer plus de responsabilits et de titres (Committer PMC), jusquau titre suprme de membre de la fondation Apache. Committer2 Le monde open-source identie les personnes qui ont un accs libre en modication sur un projet comme committer, cest--dire autoris effectuer un commit sur le gestionnaire de code source du projet. Ce statut est accord aux membres actifs du projet qui

1. http://www.apache.org/. 2. http://www.apache.org/foundation/how-it-works.html#committers.

286

Encore plus loin avec Maven

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 Conuence6, 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. Enn, 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 qualis de logiciels libres. Mais cela ne signie 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 modier, 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/conuence/. 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, dnit un Project Management Commitee, constitu de committers plus expriments ou plus actifs que les autres et qui peuvent ainsi dnir de manire efcace les orientations du projet. Le PMC a ainsi la responsabilit de voter la livraison dune nouvelle version, ou dinviter de nouveaux membres comme committers.

Les concepts Maven


API Acronyme de Application Programming Interface, il sagit de lensemble des classes qui dnit comment manipuler un programme ; elles sont donc documentes et stables dans le temps (les classes internes pouvant voluer sans prvenir). Maven propose ses propres API, en particulier pour lcriture de plugins, les fameux Mojos, mais aussi pour la manipulation des Artefacts et des Repository. Archetype Patron de cration de projet Maven, un archtype est un excellent moyen dobtenir un squelette fonctionnel de projet, plus ou moins avanc selon larchtype considr. Le plugin archetype permet la fois de crer un archtype partir dun projet existant et de crer un nouveau projet partir dun archtype. Artefact Traduction un peu trop littrale de langlais artifact Vincent nous signale quau Qubec il sagit bien dun mot il dnit un lment tangible produit lors de la phase de ralisation dun logiciel. Il peut sagir tout aussi bien dun programme excutable que dun document ou un modle UML. Dans la grande majorit des cas, il sagit de bibliothques Java. Assembly Les assembly permettent de construire un livrable selon un format particulier, typiquement une archive contenant divers artefacts ou chiers issus de la construction du projet. Le plugin associ propose plusieurs descripteurs dassembly standards, permettant par exemple de fournir les sources du projet ou dassembler un JAR contenant toutes les dpendances.

10. http://www.apache.org/foundation/how-it-works.html#pmc-members.

288

Encore plus loin avec Maven

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 dnit 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 dnissant des options dans cette variable systme. Sur un projet un peu trop gnreux, vous pouvez par exemple rencontrer des OutOfMemoryError: vous pouvez alors dnir 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 congurer 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 exibilit (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 chiers XML, qui peuvent senrichir mutuellement via un mcanisme dhritage et de prols. Autrement dit, le POM nest pas juste lquivalent mmoire du chier pom.xml. Les versions venir de Maven supporteront dailleurs des formats alternatifs - moins verbeux par exemple. Prole Un prol permet de regrouper une partie de la conguration 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 quali, trac et mis disposition des utilisateurs est quali 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 le://) 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

Encore plus loin avec Maven

Partie III

apporte de nombreuses fonctionnalits dadministration. Il existe plusieurs serveurs de rfrentiels comme Archiva13, Nexus14, Artifactory15... SCM16 Acronyme de Source Code Management (gestion du code source). Terme gnrique qui recouvre tous les outils permettant de conserver lhistorique des modications dans le code source et de travailler de manire cooprative sur un mme projet, en se synchronisant intervalles rguliers. Les outils les plus courants sont CVS, Subversion, ou Visual SourceSafe, mais il en existe bien dautres (Perforce, Git, Mercurial, Clearcase, etc.). Sous projet de Maven, SCM est une API standardise offrant toutes les fonctions communes aux SCM. Scope Le scope permet de prciser dans quel contexte une dpendance est ncessaire au projet. Par dfaut, compile correspond une dpendance utilise explicitement dans le code source ; runtime rduit ce besoin lexcution, mais pas la compilation (par exemple : pilote JDBC) ; test permet disoler les outils de test et de ne pas risquer de les rfrencer dans le code source ; provided permet de rfrencer une dpendance qui fait partie de lenvironnement cible (API JEE par exemple) ; enn, import permet de rutiliser le <dependencyManagement> dun autre POM sans passer par lhritage. Settings La conguration locale de Maven est base sur un chier XML plac dans le rpertoire $HOME/.m2 de lutilisateur (soit C:\Documents and settings\votre_nom\.m2 pour les utilisateurs de Windows). Ce chier permet dajuster le fonctionnement de Maven aux spcicits de votre poste, de votre connexion rseau, ainsi qu votre infrastructure. On y dclare par exemple des sites miroirs pour les dpts dartefacts et les identiants/ mot de passe (ce dernier peut tre crypt) pour accder aux serveurs. Un schma XML est disponible17 pour vous aider saisir ce chier sans erreur. Snapshot Dernire version dun artefact en cours de dveloppement. Une version Snapshot peut donc tre mise jour tout moment. Maven vrie une fois par jour (par dfaut) que ses Snapshots sont jour, an dviter un accs systmatique aux dpts. Loption -U permet de forcer cette vrication, par exemple sur le serveur dintgration continue.
13. http://archiva.apache.org. 14. http://nexus.sonatype.org/. 15. http://www.jfrog.org/. 16. http://maven.apache.org/scm. 17. http://maven.apache.org/settings.html.

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 ger 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 modis, ce qui peut donc entrainer des rgressions ou des incompatibilits. Staging An dassurer la qualit du livrable dun projet, une option gnralement retenue dans le processus de livraison est de construire ce dernier dans son tat nal 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 suft de le transfrer de cet espace vers lespace public, sans aucune modication 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.

Ceux qui font tourner Maven


ClassWorlds21 Maven permet chaque plugin de disposer dun espace priv dexcution, depuis lequel il peut sexcuter avec ses dpendances sans tre inuenc par les autres plugins. Ce cloisonnement est ralis par un jeu de ClassLoaders, bass sur loutil open-source ClassWorlds. Dune certaine faon, ClassWorlds peut tre compar OSGi, mme si son cadre est moins large et quil ne fait lobjet daucune normalisation.
18. http://maven.apache.org/surere. 19. http://www.junit.org/. 20. http://testng.org/. 21. http://classworlds.codehaus.org/.

292

Encore plus loin avec Maven

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 nal (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 exibilit ? le code actuel de Maven 2 souffrant un peu du poids des nombreuses annes de corrections diverses. Modello24 Les divers chiers XML manipuls par Maven sont dnis partir dun modle (dcrit dans des chiers *.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 dnie 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

Et tout ce qui tourne autour


Apt28 Format de documentation utilis couramment sur les projets Maven. Acronyme de Almost Plain Text, il sagit dun format en texte brut, comparable une syntaxe Wiki. FML29 Acronyme de FAQ Markup Language, il sagit dun format documentaire bas sur XML pour produire des Foires Aux Questions sur un site web produit par Maven. OSGi La norme OSGi dnit une plateforme de service permettant le chargement et le remplacement chaud de services, tout en grant leurs dpendances et les ventuels conits associs. Eclipse30 est lun des utilisateurs dOSGi le plus connu (bas sur limplmentation OSGi Equinox31). Maven entre en concurrence directe avec OSGi pour la dclaration des dpendances et la gestion de leurs conits. Nexus 32 est un des premiers serveurs grer la fois les rfrentiels au format Maven et au format OSGi. Wiki Systme de gestion de contenu web permettant de rendre chaque page ditable par des personnes autorises. Maven utilise Conuence33 comme Wiki. Xdoc34 Format de documentation bas sur XML permettant de dnir la structure du document, un peu comme le ferait HTML si son usage navait pas t dform des ns de mise en page par des annes de mauvaises pratiques.

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

Encore plus loin avec Maven

Partie III

Liens utiles
Et pour nir, quelques liens indispensables ajouter dans vos favoris :
m

http://maven.apache.org/. Le site ofciel de Maven, avec une documentation imparfaite mais tout de mme bien utile. http://www.maestrodev.com/better-build-maven. Premier livre sur Maven disponible en ligne gratuitement. http://www.sonatype.com/products/maven/documentation/book-defguide. Le fameux denitive 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. http://www.sonatype.com/people/. Le blog de Sonatype, sur lequel on peut piocher de nombreuses bonnes ides autour de Maven. http://mojo.codehaus.org/. Site communautaire qui hberge de nombreux plugins Maven. Si vous avez dvelopp un plugin intressant, nhsitez pas le proposer comme contribution.

Sans oublier bien-sr deux sites absolument indispensables dans la vie dun dveloppeur Java :
m m

http://blog.aheritier.net/. Le blog dArnaud. http://blog.loof.fr/. Le blog de Nicolas.

Index
Symboles $HOME 101 A Apache Ant 240 EasyAnt 242 Ivy 242 mutualisation du build 108 prsentation 6 Apache, prsentation 256 APT 202 Archtype create-from-project 229 dnition 228 Archiva 105 Artifactory 105 B Bibliothque conits 25 dclinaisons 21 dpendances transitives 24 dploiement 172 dsillusions 27 doublons 28 erreurs de tlchargement 91 gestion centralise 111 installation manuelle 94 les difcults 18 mise niveau 18 moteur de recherche 92 notion de dpendance 23 solution de facilit 19 somme de contrle 96 Branche 165 C Cargo 132 dploiement du livrable 167 Checkstyle 193 Classier 67, 107 ClassWorlds 180 Clover 196 Cobertura 196 Compilateur version cible 33 Continuum 68, 116 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 E Eclipse dclinaisons 142 difcults 148 support Maven 143 sysdeo-tomcat 136 Web Tools Platform 135 Emma 196 exclusions 29

numro de build 210 prsentation 68 production du livrable 219 J 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 L F

FindBugs 194 G Gestionnaire de sources, utilisation 17 Groovy plugin 183 script 174 H Hritage, prsentation 108 Hudson 116, 206 prsentation 69 I Idea 149 Intgration continue au-dl 166 choisir 70 multi-module 115 multi-niveau 85

Licence GPL 94 propritaire 94 SUN BCL 98 M m2eclipse 143 interrogations 149 prol ddi 270 MANIFEST 126, 212 Maven 3 objectifs 251 prsentation 251 quand ? 255 refactoring 252 roadmap 254 Maven, installation 8 Mtadonnes, pertinence et qualit 29 Module architecture 117 dcoupe 117 nos recommandations 265

Index

297

N NetBeans 153 Nexus 104 O optional 28, 127 nos recommandations 269 OSGi 221 compatibilit 253 conit 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 conguration 35 cxf 49 dbunit 80 dependency 30 documentation 36 ear 126

eclipse 142 diteur 145 ejb 124 enforcer 113 expression 177 tness 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 surere 130 tches (goals) 41 tester 185 testing-harness 186 version 40 war 135 pluginManagement 113 reports 199 PMD 195 POM dnition 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

298

Apache Maven

Prol 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 Selenium 128 settings.xml 103 SNAPSHOT 160, 215 nos recommandations 269 Sonar 204 Sonatype 257 open-source 257 stage 164 T Test accs aux chiers 60 automatisation 56 du dploiement 132

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 Utilitaires, outils de test 65 V Version centralisation 268 dnition 13 gestion centralise 111 homongnit 267 identication 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 simplie 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 ctif, inspir de leurs expriences sur le terrain, dont ils dtaillent toutes les phases successives. Ce projet volue au l des besoins et de la contribution de dveloppeurs aux prols diffrents, vous familiarisant avec les concepts fondamentaux de Maven et leur mise en uvre pratique, mais aussi avec les fonctionnalits plus avances. Vous protez 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.
TABLE DES MATIRES

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

propos des auteurs :


Nicolas De loof est techno-veilleur et architecte Java pour une grande SSII franaise. Avec 12 ans de dveloppement dans ses bagages, il a rejoint lquipe de dveloppement Maven en 2007, en particulier pour le support de GWT. Crateur du BreizhJug, groupe dutilisateurs de Java Rennais, en 2008, il participe activement au microcosme Java francophone. Arnaud Hritier est responsable des pratiques et outils de dveloppement chez eXo Platform. Depuis 10 ans il participe aux dveloppements dapplications en Java que ce soit en tant que programmeur ou architecte. Il contribue diffrents projets open-source et en particulier Maven dont il a rejoint lquipe de dveloppement en 2004 et intgr le comit de direction en 2005.

Programmation

Niveau : Tous niveaux Conguration : Multiplate-forme

Pearson Education France 47 bis, rue des Vinaigriers 75010 Paris Tl. : 01 72 74 90 00 Fax : 01 42 05 22 17 www.pearson.fr

ISBN : 978-2-7440-4098-6