Apache Maven
Apache Maven (couramment appelé Maven) est un outil de gestion et d'automatisation de production des projets logiciels Java en général et Java EE en particulier. Il est utilisé pour automatiser l'intégration continue lors d'un développement de logiciel. Maven est géré par l'organisation Apache Software Foundation. L'outil était précédemment une branche de l'organisation Jakarta Project.
Développé par | Apache Software Foundation |
---|---|
PremiĂšre version | |
DerniĂšre version | 3.9.2 () |
DĂ©pĂŽt | gitbox.apache.org/repos/asf/maven.git |
Ăcrit en | Java |
SystĂšme d'exploitation | Multiplateforme |
Environnement | Machine virtuelle Java |
Formats lus | Maven metadata (d) |
Formats Ă©crits | Maven metadata (d) |
Type |
Automate de construction Gestionnaire de paquets |
Licence | Licence Apache version 2.0 |
Site web | maven.apache.org |
L'objectif recherché est de produire un logiciel à partir de ses sources, en optimisant les tùches réalisées à cette fin et en garantissant le bon ordre de fabrication.
Il peut se comparer au systĂšme make sous Unix ou Ă l'outil Ant.
Maven utilise un paradigme connu sous le nom de Project Object Model (POM) afin de décrire un projet logiciel, ses dépendances avec des modules externes et l'ordre à suivre pour sa production. Il est livré avec un grand nombre de tùches prédéfinies, comme la compilation de code Java ou encore sa modularisation.
Un élément clé et relativement spécifique de Maven est son aptitude à fonctionner en réseau. Une des motivations historiques de cet outil est de fournir un moyen de synchroniser des projets indépendants : publication standardisée d'information, distribution automatique de modules jar. Ainsi en version de base, Maven peut dynamiquement télécharger du matériel à partir des dépÎts logiciels connus. Il propose ainsi la synchronisation transparente de modules nécessaires.
Maven1 et Maven2 ont été développés en parallÚle mais les versions ultérieures sont fondées sur la structure de la deuxiÚme version. Les parties suivantes de l'article traitent en priorité Maven2. Une version 3 de Maven est sortie le . La fin de support de la version 2 a été actée le [1].
Project Object Model (POM)
Chaque projet ou sous-projet est configuré par un POM qui contient les informations nécessaires à Maven pour traiter le projet (nom du projet, numéro de version, dépendances vers d'autres projets, bibliothÚques nécessaires à la compilation, noms des contributeurs, etc.). Ce POM se matérialise par un fichier pom.xml
à la racine du projet. Cette approche permet l'héritage des propriétés du projet parent. Si une propriété est redéfinie dans le POM du projet, elle recouvre celle qui est définie dans le projet parent. Ceci introduit le concept de réutilisation de configuration.
Le fichier pom du projet principal est nommé pom parent.
Il contient une description détaillée de votre projet, avec en particulier des informations concernant le versionnage et la gestion des configurations, les dépendances, les ressources de l'application, les tests, les membres de l'équipe, la structure et bien plus.
Convention plutĂŽt que configuration
Maven impose une arborescence et un nommage des fichiers du projet selon le concept de Convention plutÎt que configuration. Ces conventions permettent de réduire la configuration des projets, tant qu'un projet suit les conventions. Si un projet a besoin de s'écarter de la convention, le développeur le précise dans la configuration du projet.
Voici une liste non exhaustive des répertoires d'un projet Maven :
/src
: les sources du projet/src/main
: code source et fichiers source principaux/src/main/java
: code source/src/main/resources
: fichiers de ressources (images, fichiers annexes, etc.)/src/main/webapp
: webapp du projet/src/test
: fichiers de test/src/test/java
: code source de test/src/test/resources
: fichiers de ressources de test/src/site
: informations sur le projet et/ou les rapports générés à la suite des traitements effectués/target
: fichiers résultat, les binaires (du code et des tests), les packages générés et les résultats des tests
Cycle de vie
Les buts (goals en anglais) principaux du cycle de vie d'un projet Maven sont dans l'ordre :
compile
test
package
install
deploy
L'idĂ©e est que, pour n'importe quel but, tous les buts en amont doivent ĂȘtre exĂ©cutĂ©s sauf s'ils ont dĂ©jĂ Ă©tĂ© exĂ©cutĂ©s avec succĂšs et qu'aucun changement n'a Ă©tĂ© fait dans le projet depuis. Par exemple, quand on exĂ©cute mvn install
, Maven va vérifier que mvn package
s'est terminé avec succÚs (le jar existe dans target/
), auquel cas cela ne sera pas ré-exécuté.
D'autres buts sont exécutables en dehors du cycle de vie et ne font pas partie du cycle de vie par défaut de Maven (ils ne sont pas indispensables). Voici les principaux :
clean
assembly:assembly
site
site-deploy
- etc.
Ils peuvent nĂ©anmoins ĂȘtre rajoutĂ©s au cycle de vie via le POM.
Gestion des dépendances
Dans l'outil Maven, la gestion des dépendances s'appuie sur deux notions :
- l'héritage
- les relations transitives (ou transitivité)
La notion de relation transitive est implémentée pour la relation "dépend de" et l'ensemble projet Java.
Exemple : Soit trois projets (A, B, C), si A dépend de B, et B dépend de C, alors A dépendra de C.
Par défaut dans Maven, la transitivité est configurée en automatique. Cette configuration peut générer des contraintes avec les projets volumineux :
- l'inclusion de jars dans les EAR
- l'inclusion de versions non-désirées
- la prĂ©sence de dĂ©pendances pour diffĂ©rentes versions Ă diffĂ©rents niveaux de la transitivitĂ© (un projet A dĂ©pend dâun projet C.x et d'un projet B, et ce dernier dĂ©pend du projet C.y)
- une perte d'informations (des dépendances effectives, par exemple) et la présence de dépendances inutiles à d'autres projets.
Dans l'attente d'une amĂ©lioration du plugin, cette option est dĂ©sactivable en configurant lâoption provided.
Référentiel (ou entrepÎts)
Un autre apport de l'outil Maven est son organisation des projets et plugins. Maven dispose de plusieurs rĂ©fĂ©rentiels Ă plusieurs niveaux. Le but du rĂ©fĂ©rentiel est de rendre disponible aussi bien les plugins utilisĂ©s ou envisagĂ©s de lâĂȘtre que les projets gĂ©nĂ©rĂ©s par Maven. On peut bien sĂ»r y installer des projets pour les utiliser (sans quâils ne soient gĂ©nĂ©rĂ©s par Maven). Il y a trois rĂ©fĂ©rentiels :
- Un au niveau de la machine du développeur, appelé repository local, il inclut tout ce que le développeur a utilisé et a développé.
- Un au niveau du site Maven qui contient lâensemble des plugins. Il est en augmentation continue. Il est ouvert Ă tout le monde, en consĂ©quence des mises Ă jour pourraient ĂȘtre incohĂ©rentes ou incompatibles avec dâautres.
- Pour Ă©viter ceci, il y a un troisiĂšme rĂ©fĂ©rentiel (facultatif) qui peut ĂȘtre dĂ©clarĂ© au niveau de lâentreprise ou la structure utilisant Maven, il joue lâintermĂ©diaire entre les deux premiers rĂ©fĂ©rentiels, il inclut les plugins (â maĂźtrise des versions et des mises Ă jour) et les projets (les rendant accessible Ă lâensemble des dĂ©veloppeurs).
Pour crĂ©er un rĂ©fĂ©rentiel pour lâentreprise (ou un rĂ©fĂ©rentiel commun en gĂ©nĂ©ral), on peut utiliser les protocoles ftp, scp, file et http.
Remarque : le plugin fourni pour le protocole ftp peut poser problĂšme car il n'est pas encore au point.
Pour installer un jar dans le rĂ©fĂ©rentiel (sans quâil ne soit un projet maven), il faut bien gĂ©nĂ©rer le POM avec lui. Sans cela Maven essaye de se connecter dans les diffĂ©rents rĂ©fĂ©rentiels pour le chercher d'oĂč une rĂ©elle perte de temps vu que le jar nâest pas supposĂ© ĂȘtre prĂ©sent dans ces rĂ©fĂ©rentiels.
Une derniĂšre remarque, de taille : dans le rĂ©fĂ©rentiel, il y a une structure bien dĂ©finie et inchangeable (qui permet Ă Maven de trouver son chemin), oĂč les jar et les projets sont organisĂ©s selon le groupId, artifactId puis la version.
Donc une fois une dĂ©claration faite (dĂ©pendance ou autre), Maven cherche dans lâemplacement suivant :
{emplacement Repository}/groupId/artifactId/version
Les noms des packages, eux, sont comme suit :
{artifactId}-{version}.{package}
Et Ă lâopposĂ© du rĂ©pertoire "target" oĂč on peut dĂ©finir le nom de notre package, il nâest pas permis de changer les noms ou la structure des packages sous peine de non-reconnaissance de package et donc de "BUILD FAILED".
Rapports
Les rapports générés par Maven portent notamment sur :
- les dépendances du projet
- les résultats des tests lancés, incluant:
- des statistiques sur les résultats
- le pourcentage dâefficacitĂ© de ces tests
- le pourcentage de code testé
- la complexité du code
- le respect des normes de codage
Plugins
Les plugins permettent l'ajout de fonctionnalitĂ©s. Ces plugins sont disponibles sur le site de Maven, ou, Ă dĂ©faut, peuvent ĂȘtre dĂ©veloppĂ©s. Pour utiliser un plugin, il suffit de le dĂ©clarer dans le POM.
Il est Ă noter que la dĂ©claration est hĂ©ritĂ©e par dĂ©faut. La dĂ©claration se fait dâune maniĂšre simple : groupId (si aucun nâest dĂ©clarĂ©, il prend celui par dĂ©faut org.apache.maven), artifactId et Ă©ventuellement la version (sinon, câest la derniĂšre version qui est utilisĂ©e).
- Exemple d'installation d'artifactId dans pcm-fo
set JAVA_HOME=C:\Program Files\Java\jdk1.6.0_38<br /> set M2_HOME=C:\dev\maven\apache-maven-3.0.4-bin\apache-maven-3.0.4<br /> set PATH=%JAVA_HOME%/bin;%M2_HOME%/bin;%PATH%<br /> pause call mvn install:install-file -Dfile=solr-webapp-3.4.0.war -DgroupId=org.apache.solr -DartifactId=solr-webapp -Dversion=3.4.0 -Dpackaging=war pause call mvn install:install-file -Dfile=jodconverter-core-3.0-beta-4.jar -DgroupId=org.artofsolving.jodconverter -DartifactId=jodconverter-core -Dversion=3.0-beta-4 -Dpackaging=jar pause call mvn install:install-file -Dfile=parsley-flex4-2.4.1.swc -DgroupId=org.spicefactory -DartifactId=parsley-flex4 -Dversion=2.4.1 -Dpackaging=swc pause call mvn install:install-file -Dfile=spicelib-util-3.0.0.swc -DgroupId=org.spicefactory -DartifactId=spicelib-util -Dversion=3.0.0 -Dpackaging=swc pause call mvn install:install-file -Dfile=spicelib-reflect-3.0.0.swc -DgroupId=org.spicefactory -DartifactId=spicelib-reflect -Dversion=3.0.0 -Dpackaging=swc pause call mvn install:install-file -Dfile=legacy-spicelib-utils-2.5.0.swc -DgroupId=org.spicefactory -DartifactId=legacy-spicelib-utils -Dversion=2.5.0 -Dpackaging=swc pause call mvn install:install-file -Dfile=popup-1.9.swc -DgroupId=com.adobe.cairngorm -DartifactId=popup -Dversion=1.9 -Dpackaging=swc pause call mvn install:install-file -Dfile=popupParsley-1.9.swc -DgroupId=com.adobe.cairngorm -DartifactId=popupParsley -Dversion=1.9 -Dpackaging=swc pause call mvn install:install-file -Dfile=validation-1.13.swc -DgroupId=com.adobe.cairngorm -DartifactId=validation-1.13 -Dversion=1.13 -Dpackaging=swc pause call mvn install:install-file -Dfile=cairngorm-integration-0.11.swc -DgroupId=org.spicefactory -DartifactId=cairngorm-integration -Dversion=0.11 -Dpackaging=swc
AprĂšs cette dĂ©claration, lors du lancement dâune tĂąche, Maven vĂ©rifie sa prĂ©sence dans le rĂ©fĂ©rentiel local. Sâil ne trouve pas le plugin, il se connecte alors au rĂ©fĂ©rentiel central pour le tĂ©lĂ©charger. En cas d'Ă©chec de rĂ©cupĂ©ration, on termine lâexĂ©cution avec un message dâerreur (on peut Ă©viter ceci et demander Ă Maven de continuer et de donner le rĂ©sultat du traitement âavec les messages dâerreurs- Ă la fin).
Maven et Eclipse
Eclipse permet de gĂ©nĂ©rer des packages, mais ces derniers ne respectent pas la structure de Maven et ne sont pas non plus installĂ©s dans le rĂ©fĂ©rentiel. Cela implique que sans lâutilisation dâun outil externe, il faut installer manuellement tous les packages gĂ©nĂ©rĂ©s.
Un plugin Maven pour Eclipse est disponible, permettant Ă Eclipse dâutiliser Maven en arriĂšre-plan et donc d'utiliser Eclipse et Maven conjointement.
Ceci permet dâavoir des projets Maven gĂ©nĂ©rĂ©s et stockĂ©s dans le rĂ©fĂ©rentiel.
Il permet notamment de dĂ©pendre de projets qui sont dans le rĂ©fĂ©rentiel, et donc on nâa pas besoin de les importer sous Eclipse comme câest le cas dans les outils existant. Le classpath est gĂ©nĂ©rĂ© par Maven.
Par contre son utilisation comporte quelques lacunes.
Si on lance la commande qui gĂ©nĂšre le classpath âmvn eclipse:eclipseâ Ă partir dâun POM parent, alors lâensemble des modules doivent ĂȘtre prĂ©sents dans lâespace de travail. La dĂ©pendance est faite Ă lâintĂ©rieur de cet espace, et pour avoir une dĂ©pendance Ă partir du rĂ©fĂ©rentiel, il faut lancer la commande pour chaque module.
Un autre problĂšme (actuellement sans solution), porte sur lâhĂ©ritage quand on ne respecte pas la hiĂ©rarchie dans les rĂ©pertoires.
- Remarques
- Dans le POM, le chemin dâaccĂšs au POM du module est dĂ©fini dans le tag module, et donc on peut utiliser des ../ pour aller Ă des rĂ©pertoires qui sont au mĂȘme niveau (une structure en plan).
- Dans le cas dâune structure en plan, le plugin Eclipse ne reconnaĂźt pas le POM parent, car par dĂ©faut il cherche dans les rĂ©pertoires au-dessus (et a priori impossible de le changer).
- Ce plugin permet Ă Eclipse de rajouter Maven comme un outil externe, au mĂȘme titre que Ant.
Intégration continue
Voici une liste non exhaustive des moteurs d'intégration continue qu'il est possible d'utiliser conjointement avec Maven :
Analyse de la qualité du code
Voici une liste non exhaustive des plates-formes d'analyse de la qualité du code source qu'il est possible d'utiliser conjointement avec Maven :
Notes et références
- « Maven â Maven Releases History », sur maven.apache.org (consultĂ© le )