Utilser Maven 2
Date de publication : 04/08/2008 , Date de mise à jour : 04/08/2008
Par
Matthieu Lux (Tous les articles)
synopsis
1. La théorie de Maven
1.1. Philosophie
1.2. Fonctionnement
2. Organisation des fichiers
3. Cycle de vie et goal Maven
3.1. Goals Maven
3.1.1. Définition
3.1.2. Localisation des goals
3.2. Cycle de vie
4. Gestion des plugins Maven
4.1. Dans Maven, tout est plugin
4.2. Cartographie
4.2.1. Core
4.2.2. Packaging
4.2.3. Outils
4.2.4. Reporting
4.2.5. IDE
4.2.6. Tous les plugins
4.3. Configurer les plugins
5. Repository Maven
5.1. Définition d'un artifact
5.2. Repository Maven 2
5.3. Configurer des repositories
6. Gestion des dépendances du projet
6.2. Dépendances du projet
6.2. Installation du projet
7. Resources et filtrage
7.1. Resources
7.2. Filtrage
7.3. Stratégies et risques du filtrage
8. Packaging
9. Integration avec Eclipse
9.1. External builder
9.1.1. Avantages
9.1.2. Inconvénients
9.2. m2Eclipse plugin
9.2.1. Avantages
9.2.2. Inconvénient
9.3. q4e
9.3.1. Avantages
9.3.2. Inconvénient
10. Integration avec Tomcat
10.1. Dans src/main/webapp : war:inplace
10.1. Avantages
10.1.1. Inconvénients
10.2. Dans target/<final-name> : war:exploded
11. Configuration du site
11.1. Structure
11.2. Contenu
11.3. Rapports
12. Heritage de pom
13. Intégration continue
13.1. Principes
13.2. Bénéfices
13.3. Intégration continue avec Maven
14. Archetypes
14.1. Utiliser un Archetype Maven
14.2. Créer un Archetype Maven
15. Projets modulaires
15.1. Définition
15.2. Utilisation
15.3. Intérêts et développements
1. La théorie de Maven
1.1. Philosophie
Ant propose une boite à outils pour la compilation de projets Java. Maven gère
toute l'application en proposant une facon de faire commune afin d'avoir une
infrastructure de projet visible, réutilisable, maintenable et compréhensible.
Maven propose une configuration par défaut très complète qui permet une
standardisation de la structure des projets Java. Néamoins Maven permet toujours
de surcharger les configurations pour s'adapter au plus de situations.
1.2. Fonctionnement
Un projet qui utilise Maven contient simplement un fichier pom.xml qui
représente la configuration du projet pour Maven. Toutes les informations pour
le projet sont à renseigner dans ce fichier.
La grande différence par rapport à un fichier build.xml Ant est que le fichier
pom.xml décrit le projet pour que Maven sache le manipuler alors qu'un build.xml
decrit entierement la procédure pour réaliser une opération technique.
2. Organisation des fichiers
Maven propose une structure de fichier complète. Il s'agit de la configuration par
défaut mais elle est surchargeable. Nous recommandons tout de même de s'en servir le
plus possible afin de profiter de la standardisation que propose Maven.
Structure des répertoires |
src/main/java |
Contient les sources Java de l'application |
src/main/resources |
Contient les resources de l'application |
src/main/webapp |
Contient les fichiers de l'application Web |
src/test/java |
Contient les sources Java pour les tests unitaires |
src/site |
Contient les fichiers pour le site |
target |
Répertoire de destination de tous les traitements Mav |
3. Cycle de vie et goal Maven
3.1. Goals Maven
3.1.1. Définition
Maven s'execute sous forme de goal. A partir de la comprehension qu'il a du
projet, il est capable d'executer énormément d'opération dessus, chaque
opération correspond à un goal.
Pour lancer un goal Maven sur un projet, il faut se placer à la racine du
projet et executer la commande :
Il est possible d'enchainer deux ou plusieurs goal avec la commande :
mvn <nom du goal 1> <nom du goal 2> <nom du goal 3>
|
3.1.2. Localisation des goals
Tous les goals se trouvent dans des plugins Maven. Pour executer un goal,
Maven va donc commencer par résoudre le nom du goal pour en déduire le
plugin dans lequel il se trouve et le télécharger.
Tous les goals maven s'ecrivent de la facon suivante :
<nom du plugin>:<nom du goal>
|
|
Maven propose toute une liste de goal reconnus par défaut sans le nom du
plugin. la plupart sont listés ici :
Principals goals Maven
|
3.2. Cycle de vie
Maven definit un cycle de vie pour le projet. Cela permet de gérer des
dépendances entre goal afin d'enchainer des goal dans le bon ordre (genre faire
les packets après avoir compilé...)
Un cycle de vie est définit par défaut dans Maven. Il est définit là :
Le cycle de vie
Par défaut, des goals sont associés aux étapes du cycle de vie. Quand on tape
une commande du type :
mvn <étape du cycle de vie>
|
Maven exécutera dans l'ordre tous les goals correspondants à chaque étape du
cycle précédent celle qui a été demandée.
C'est ce mécanisme qui permet d'utiliser des commandes tu type :
ou
Ce ne sont pas des noms de goal mais des nom d'étapes du cycle de vie auxquels
sont associés des goals : compiler:compile pour le premier cas et war:war qui
est executé pour un install dans un projet de type war (après avoir parcouru les
étapes précédente dans le cycle de vie).
4. Gestion des plugins Maven
4.1. Dans Maven, tout est plugin
Quand on télécharge Maven la première fois, on ne télécharge pratiquement que le
moteur qui sert à télécharger des plugins. Tous les goals Maven sont dans des
plugins même les plus indispensables comme le plugin compiler.
4.2. Cartographie
4.2.1. Core
-
clean : nettoie le répertoire de travail du projet : suppression des
fichiers générés, etc.
- compiler : compilation des sources du projet
-
resources : copie les ressources du projet dans le répertoire de build
(classes ou test-classes)
- site : Génère le site web du projet
- surefire : Joue les tests unitaires
- Et aussi : deploy, install, verifier
4.2.2. Packaging
- jar : construit un jar à partir du projet
- war : construit un war à partir du projet
- Et aussi : ear, ejb, rar, shade
4.2.3. Outils
-
archetype : génère une structure de projet vide à partir d'un modèle
-
assembly : génère une distribution de sources / fichiers binaires
- dependency : manipulation et analyse des dépendances
-
help : donne des informations sur l'environnement de travail du projet
-
Et aussi : ant, antrun, enforcer, gpg, invoker, one, patch, release,
remote-resources, repository, scm, source, stage, etc.
4.2.4. Reporting
- checkstyle : Génère un rapport d'audit de code checkstyle
- javadoc : Génère la javadoc du projet
- pmd : Génère un rapport PMD
-
project-info-reports : Génère un rapport standard du projet
- surefire-reports : Génère le rapport de tests unitaires
- jdepend : Génère un rapport de métriques de code
- cobertura : Génère un rapport de couverture de tests
- Findbugs : Génère un rapport d'audit de code findbugs
-
Et aussi : changelog, changes, clover, doap, docck, jxr, etc.
4.2.5. IDE
-
eclipse : Génère un fichier .project pour intégration du projet dans
eclipse
- Et aussi : idea
4.2.6. Tous les plugins
4.3. Configurer les plugins
Il est possible de configurer les plugins utilisés dans le pom.xml :
< 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 >
|
En rappelant le groupId et l'artifactId du plugin, on identifie de façon
certaine le plugin. Il est alors possible de spécifier des paramètres génériques
ou des paramètres spécifiques au plugin.
Spécifier la version peut être important. Tous les plugins peuvent avoir des
mises à jour et par défaut Maven vérifiera une fois par jour si une nouvelle
version est disponible. Il arrive que les meilleurs plugins sortent des versions
buggé, et sans fixer la version, le projet peut poser des problèmes à la
compilation d'un jour sur l'autre parce que la nouvelle version a été
téléchargée.
Dans le meilleur des scénaris, grâce à la dépendance entre pom étudié ci
dessous, un projet héritera d'un pom générique qui sélectionne au mieux les
versions de chaque plugin.
Pour les configurations spécifiques au plugin, elles se positionnent dans la
balise <configuration>. Chaque paramètre peut alors être définit de la
façon suivante : <nom du paramètre>valeur</nom du paramètre>
5. Repository Maven
5.1. Définition d'un artifact
Tous les paquets gérés par Maven sont identifié par 4 informations :
-
groupId : Définit l'organisation ou groupe qui est à l'origine du projet. Il
est formulé sous la forme d'un package Java (org.archetypejs par exemple)
-
artificatId : Définit le nom unique dans le groupe pour le projet.
-
version : Définit la version du projet. Les numéros de version sont souvent
utilisés pour des comparaisons et des mises à jour.
-
type : Type de projet. On trouvera le plus souvent : jar, war, maven-plugin,
pom...
5.2. Repository Maven 2
Maven 2 définit une structure de site Web qui permet de publier les artifacts.
En connaissant simplement la racine du site, Maven peut alors chercher sur le
site tout ce dont il a besoin. Tous les repository Maven ne contiennent pas
forcement tous les paquets.
Que ce soit pour les plugins Maven que l'on a vu précédemment ou pour les
dépendances ci desous, Maven gère un localrepository là ou il s'execute. Il y
recopie tout ce qu'il télécharge.
Le principe de Maven est de commencer à vérifier dans son localrepository la
disponibilité d'un projet avant de le chercher sur Internet. Ainsi il n'y a que
la première execution d'un nouveau goal ou d'une nouvelle résolution de
dépendance qui prends du temps. La seconde fois, les packets seront déjà
disponibles en local.
5.3. Configurer des repositories
Maven utilise toujours par défaut un serveur central qui contient énormément de
jar et la pratiquement tous les plugins Maven.
Pour ajouter des repository, il faut ajouter dans le pom.xml :
< repositories >
< repository >
< id > repo< / id >
< name > repo name< / name >
< url > url< / url >
< / repository >
< / repositories >
< pluginRepositories >
< pluginRepository >
< id > plugin repo< / id >
< name > plugin repo name< / name >
< url > url< / url >
< / pluginRepository >
< / pluginRepositories >
|
Comme on peut le voir, Maven differencie les repository qui contiennent les
plugins et ceux qui contiennent les dépendances.
6. Gestion des dépendances du projet
Plutôt que de copier explicitement tous les jar nécessaires pour un projet, Maven
propose de le définir par configuration dans le pom.xml. C'est ensuite le plugin
Maven de gestion de dépendances qui ira sur internet télécharger les jar indiqués.
6.2. Dépendances du projet
La configuration à rajouter dans le fichier pom.xml est la suivante :
< dependencies >
...
< dependency >
< groupId > org.springframework< / groupId >
< artifactId > spring-beans< / artifactId >
< version > 2.0.5< / version >
< type > jar< / type >
< scope > compile< / scope >
< / dependency >
...
< / dependencies >
|
Une très bonne proportions des jars sont aujourd'hui disponible sur les
repository Maven. Pour les trouver, le plus simple est d'utiliser le Google des
packets Maven :
http://www.mvnrepository.com/
Les seuls paramètres obligatoirs sont le groupId et l'artifactId.
Il est extremmement recommandé de toujours spécifier la version.
Sans cela Maven utilisera toujours la dernière version en date. Il est alors
tout à fait possible que lors d'une mise à jour d'une dépendance qui publierait
une nouvelle version alpha, elle soit automatiquement utilisée et empeche le
projet de tourner alors qu'aucune modification n'ait été aportée.
Le type n'est pratiquement jamais nécessaire sauf dans des cas particuliers.
Le paramètre scope est par contre à prendre en compte. Les différentes valeurs à
prendre en compte sont les suivantes :
-
compile
: C'est la valeur par défaut, la dependance sera toujours disponible dans le
classpath.
-
provided
: Indique que la dépendance est nécessaire pour la compilation mais sera
fournis par le container ou le JDK et donc ne sera pas fournis dans le
package.
-
runtime
: Indique que la dépendance est nécessaire pour l'execution mais pas pour la
compilation.
-
test
: Indique que la dépendance est nécessaire pour la compilation et
l'execution des tests unitaires.
On utilisera souvent le scope provided lorsqu'on code avec les servlet.
Effectivement, les jars sont fournis automatiquement par Tomcat mais il est
nécessaire de les avoirs pour la compilation.
6.2. Installation du projet
Tous les projets sont définits comme des paquets Maven. Il est donc possible de
publier ces paquets.
Tout d'abord pour publier dans le localrepository, il suffit d'utiliser le goal
install :
Pour l'installer sur un repository externe, il faut lui configurer dans le
pom.xml la gestion de la distribution :
< distributionManagement >
< repository >
< id > ganesh3-repo< / id >
< name > Ganesh Repository for Maven2< / name >
< url > file://${deploy.repository}< / url >
< / repository >
< / distributionManagement >
|
L'URL peut être exprimé sur beaucoup de protocoles, ici on voit file, mais cela
peut être également scp, http (à condition qu'il y ait un webdav) etc...
7. Resources et filtrage
7.1. Resources
Dans un projet Maven, src/main/java correspond au répertoire principal dans
lequel doit se trouver toutes les sources applicatives du projet. Néammoins il
est très courant d'avoir des fichiers de configuration à positionner dans le
classpath.
Le répertoire src/main/resources répond à cette attente. Il s'agit d'un autre
répertoire qui sera compilé et ajouté au classpath. Son rôle est de contenir
l'ensemble des fichiers de configuration du projet.
Pour modifier le répertoire de resources ou pour en ajouter d'autres, il faut
rajouter dans le pom :
< build >
< resources >
< resource >
< directory > src/main/resources< / directory >
< / resource >
< / resources >
< / build >
|
7.2. Filtrage
Mais les resources n'ont pas pour seul objectif de séparer les fichiers de conf
pour amméliorer la visibilité. Même si ce n'est activé par défaut, le principal
atout est de pouvoir réaliser du filtrage sur ces fichiers.
Filtrer les fichiers correspond à remplacer à l'intérieur de tous les fichiers
et à chaque compilation tous les ${properties} par leur valeur. Pour activer le
filtrage sur un répertoire de resources, il faut ajouter le code suivant :
< build >
< resources >
< resource >
< directory > src/main/resources< / directory >
< filtering > true< / filtering >
< / resource >
< / resources >
< / build >
|
Par défaut, les properties qui seront utilisés pour le filtrage sont les
properties actifs dans Maven, il y en a plusieurs positionnées par défaut tel
que pom.name, pom.version...
Il est possible d'ajouter un fichier de properties qui sera utilisé pour le
filtrage. Ils sont alors positionné par convention dans le répertoire
src/main/filters et se configure avec le code suivant :
< build >
< filters >
< filter > src/main/filters/filter.properties< / filter >
< / filters >
< / build >
|
7.3. Stratégies et risques du filtrage
Le filtrage a été fait pour gérer les configuration par environnements pour les
projets. Il y a plusieurs stratégies possible pour gérer les environnements :
-
Sélectionner le fichier de filtrage en fonction de l'environnement :
<filter>src/main/filters/${env}.properties</filter>
-
Gérer des profils (voir le chapitre consacrés aux profils) afin de
positionner des properties par profils.
Quelque soit la solution utilisée, cela permet de sélectionner l'environnement
pour lequel on veut configurer l'application et les fichiers de configuration
seront automatiquement positionnés avec les bonnes valeurs.
Le risque de cette méthode réside dans la phase de développement. Si dans la
phase de développement, la gestion de la compilation n'est pas gérée par Maven,
le filtrage ne sera pas effectué. Comme les fichiers du répertoire resources
seront remplis de ${bdd.url} (par exemple) ils ne pourront être utilisés
directement.
L'utilisation des filtres lie donc le développeur avec le mécanisme de
compilation de Maven.
8. Packaging
Le packaging fait partie intégrante du cycle de vie d'un projet Maven. Il est
toujours nécessaire de transformer un projet en une archives uniques afin de pouvoir
le publier dans un repository.
Maven est construit à partir de tous les standards de SUN, le packaging de maven en
revient donc toujours à construire l'archives suivant ces standards.
La commande pour avoir le packaging de son projet est :
Bien évidemment, Maven prends en compte le type du projet et fera un .jar pour une
librairie, un .war pour une application Web etc...
9. Integration avec Eclipse
Maven a pour but de gérer le projet pendant tout son cycle de vie. Depuis le poste
de développement jusqu'a la livraison en production (du moins sur le papier).
Eclipse permet à l'utilisateur d'agir efficacement sur le projet, pour cela il a
besoin de le comprendre en détail.
Conclusion, les deux outils utilisent une configuration complète et indépendante du
projet.
"Intégrer" des deux outils correspond alors à faire communiquer les configurations
de Maven et d'Eclipse. La partie critique correspond souvent à fournir à Eclipse le
classpath qui correspond à la gestion des dépendances de Maven.
Plusieurs stratégies qui peuvent être mise en place pour cela. Les 3 qui sont
présentées ici sont viables, elles présentent chacun leurs avantages et
inconvénient.
9.1. External builder
Maven propose son plugin d'intégration pour Eclipse. Sa principale compétence
est d'être capable d'écrire la configuration Eclipse à partir de son pom.xml.
Ce mécanisme est sur et abouti. La configuration Eclipse générée par Maven est
toujours valide et lorsque la configuration existe déjà, Maven se contente de la
compléter pour la bonne marche du projet. Noter que l'utilisation du plugin peut
être afinée notamment pour activer la prise en charge de WTP.
mvn eclipse:eclipse -Dwtpversion=1.5
|
Pour avoir tous les détails, se référer au site du plugin : maven-eclipse-plugin
Pour automatiser les développement, il faut alors configurer le lancement des
commandes Maven dans les "builders" Eclipse. Pour cela, il faut aller dans les
propriété du projet, puis builders. Ajouter un nouveau builder externe avec la
configuration suivante :
- location : l'emplacement de mvn.bat
-
working directory : le projet sur lequel on veut executer la tâche
- arguments : la ou les directives Maven à utiliser.
On associera le plus souvent le déclenchement du builder uniquement sur les
builds manuel afin de ne pas avoir Maven qui se déclenche dès qu'on sauvegarde
un fichier.
Avec ce mécanisme, le plus pratique est de créer le builder suivant :
- se déclenche sur la modification du fichier pom.xml
- execute la directive eclipse:eclipse
- met à jour tous le projet une fois terminé
Avec ce builder, les dépendances du projets seront toujours à jour sous réserve
d'avoir demandé explicitement un build.
9.1.1. Avantages
Cette méthode permet de gérer précisément les directives Maven à utiliser et
leur déclenchement.
9.1.2. Inconvénients
A force d'édition des fichiers de configuration d'Eclipse par Maven,
l'interface a tendance à perdre les pédales. Les fichiers de configuration
ne sont jamais altéré mais Eclipse a parfois besoin de plusieurs "F5" pour
retrouver sa configuration.
9.2. m2Eclipse plugin
Le plugin m2Eclipse est le plus aboutis des plugins Maven pour Eclipse à l'heure
actuelle (juillet 2008). Ses principales fonctionnalités sont de gérer une
librairie dynamique représentant les dépendances de Maven et de fournir un
builder Maven simplifié.
A noter qu'il est également intégré dans le plugin eclipse de Maven, aussi vous
pouvez utiliser
Pour pousser l'intégration jusqu'au projet web lançable avec Eclipse WTP, vous
pouvez utiliser
mvn eclipse:m2eclipse -Dwtpversion=1.5
|
m2eclipse propose maintenant une interface complète pour importer un projet
Maven dans Eclipse. Soit à partir d'un système de gestion de ressource :
- Cliquer sur File -> Import ....
- Sélectionner Other -> Checkout Maven project from SVN
Soit à partir du projet sur le disque dur :
- Cliquer sur File -> Import ....
- Sélectionner General -> Maven project
9.2.1. Avantages
Permet de s'abstraire du builder eclipse:eclipse et des problématiques de
rechargement de la configuration Eclipse.
9.2.2. Inconvénient
m2eclipse a récemment essuyer ses principales faiblesses et se positionne
comme le projet qui fera un jour partie intégrante d'Eclipse.
Il n'a de faiblesse qu'en cherchant les fonctionnalités avancées de Maven
tel que les filtrages même s'il propose maintenant des solutions ou la
gestion des projets multi-modules.
9.3. q4e
q4e est le principal concurent de m2eclipse. La version 0.7 actuellement
disponible est déjà très stable. Projet q4e
En terme de service, il propose la gestion dynamique des dépendances Maven tout
comme m2Eclipse. Il propose également plusieurs interfaces dont une pour lancer
des directives.
9.3.1. Avantages
Il est déjà opérationnel et se montre très prometteur.
9.3.2. Inconvénient
Le fonctionnel semble encore trop limité pour les projets utilisant des
fonctionnalités avancées de Maven.
10. Integration avec Tomcat
Par défaut Maven gère les fichiers sources dans le répertoire src et les fichiers
compilé dans le répertoire target. Et ce, même si la compilation ne fournis pas
d'autre valeur ajoutée que la recopie du fichier.
La question du fonctionnement avec le développement sous Tomcat se pose alors. On a
l'habitude de pouvoir modifier directement les fichiers utilisés par Tomcat ce qui
permet de ne pas le redémarrer pour tester les modifications (du moins pour les
fichiers statiques).
On démarre toujours Tomcat dans un répertoire webapp racine. La question est alors
de savoir si on démarre tomcat dans le répertoire src/main/webapp ou
target/<final-name>.
10.1. Dans src/main/webapp : war:inplace
Cela va un peu à l'encontre des grands principes de Maven. Si on démarre Tomcat
dans le répertoire src, cela veut dire qu'il faudra ajouter dans
src/main/webapp/WEB-INF/classes les fichiers compilés et dans
src/main/webapp/WEB-INF/lib les dépendances.
La commande war:inplace réalisera cette opération automatiquement. En
configurant Eclipse pour positionner sa sortie de compilatation dans le
répertoire src/main/webapp/WEB-INF/classes, tout fonctionnera correctement.
Cette solution est à privilégier dès qu'elle est possible car elle apporte les
meilleurs possibilité aux developpeurs. Malheureusement certaines limitations la
rende innutilisable dans certains cas.
10.1. Avantages
C'est une solution très pratique car après une initialisation par la
commande war:inplace, il est possible de développer avec Tomcat sans
utiliser Maven et en profitant de toutes les modifications dans Tomcat
intantanément.
10.1.1. Inconvénients
-
En ne passant plus par Maven pour la compilation, on perd beaucoup des
fonctionnalitées de Maven. Par exemple, il n'est pas possible d'utiliser
le filtrage de resource. Comme Eclipse ne le gère pas, les fichiers qui
seront copiés dans src/main/webapp/WEB-INF/classes ne seront pas
filtrés.
-
Dans certain projet, il y a un mécanisme de dépendance entre application
Web. Cela permet de récupperer dans la webapp des fichiers d'une
dépendance. Dans ce cas, le goal war:inplace va recopier les dépendances
dans le répertoire src/main/webapp. Pour gérer les commit des sources du
projet, il faut faire particulièrement attention à ne pas commité les
fichier hérité dans le projet au risque desurcharger les fichiers et ne
perdre la dépendance.
-
Si le projet et modulaire (voir plus bas) aucun répertoire ne pourra
servir de base à Tomcat, le fonctionnement est donc impossible.
10.2. Dans target/<final-name> : war:exploded
La propriété final name dans maven correspond au nom du package à utiliser. Il
se configure comme ceci :
< build >
< final-name > package-name< / final-name >
...
< / build >
|
La commande war:exploded va créer un répertoire target/<final-name> qui
contiendra le war de l'application sans réaliser l'archive.
En configurant Tomcat pour démarrer dans ce répertoire, il utilisera les
fichiers compilés par Maven. L'avantage est que l'on reste entièrement dans le
cadre de Maven, pas d'entorses au concept : src d'un côté, fichiers compilés de
l'autre. On profite de tous les mécanismes de Maven : filtrage, projets
modulaire, dépendances des fichiers de la webapp...
L'inconvénient est qu'il faut passer par Maven pour toutes modification des
fichiers. Cette opération peut être fastidieuse.
11. Configuration du site
Maven propose de générer un site présentant le projet. Toujours fidèle à ses
principes, Maven pourra générer un site minimal même sans disposer de configuration
spécifique. Le commande à utiliser est la suivante :
(ou)
Le site est alors générer dans le respertoire target/site. Une fois habituer à ce
genre de site, vous reconnaitrait plusieurs sites officiels de grands frameworks
générer par ce moyen :
Tapestry
,
Struts
,
EhCache
ou bien sur
Maven
lui même.
Un des gros atouts de cette fonctionnalité est de permettre la regénération
automatique et fréquente du site présentant la documentation ainsi que les rapports
du type JavaDoc ou tests unitaires. Le plus souvent, avec l'utilisation de systèmes
d'intégration continue, la génération du site est configuré pour être lancé à chaque
build afin de pouvoir suivre les rapports au fur et à mesure.
11.1. Structure
Par défaut, Maven va créer quelques pages présentant les informations présente
dans le pom (si elles y sont) comme la description générale, la gestion des
sources ou l'outil de ticketing...
Les fichiers pour le site seront à déposer dans le répertoire src/site prévu à
cet effet. On l'organisera alors ainsi :
+- src/
+- site/
+- apt/
| +- index.apt
|
+- xdoc/
| +- other.xml
|
+- fml/
| +- general.fml
| +- faq.fml
|
+- site.xml
|
Le fichier site.xml permet de gerer la structure du site et principalement le
menu, se référer à la documentation pour la syntaxe.
Il y a ensuite deux fonctionnalités principales pour enrichir le contenu du site
: rajouter du contenu, et rajouter des rapports.
11.2. Contenu
Il est possible de rajouter des pages de contenu dans plusieurs format
différents :
Les fichiers pour chaque format doivent être positionner dans le répertoire
correspondant. Dans le site généré, une page ecrite au format apt dans le
fichier src/site/apt/toto/toto.apt sera généré dans target/site/toto/toto.html
et c'est ainsi pour tous les types de fichiers.
11.3. Rapports
Certains plugins Maven proposent des rapport en plus de goals. Certains plugins
ne proposent d'ailleur que des rapports. A la génération du site, Maven
executera tous les rapports configurés pour les calculer.
Pour ajouter un rapport dans le site Maven, il faut rajouter dans le pom une
configuration de ce type :
< reporting >
< plugins >
...
< plugin >
< groupId > org.apache.maven.plugins< / groupId >
< artifactId > maven-project-info-reports-plugin< / artifactId >
< version > 2.0.1< / version >
< / plugin >
...
< / plugins >
< / reporting >
|
En fait, le site par défaut contient justement le rapport du plugin
maven-project-info-reports-plugin
Les plugins les plus courant proposant des rapports sont les suivants :
-
changelog
: Génère la liste des changements récent du gestionnaire de source
-
changes
: Génère le rapport du système de ticketing du projet
-
checkstyle
: Génère le rapport de checkstyle
-
javadoc
: Génère la JavaDoc du projet
-
pmd
: Génère le rapport PMD
-
project-info-reports
: Génère les rapports standards Maven
-
surefire-report
: Génère le rapport des résultats des tests unitaires
12. Heritage de pom
Un pom très complet peut devenir très conséquent. De plus, une partie importante de
son contenu sera souvent partagé entre plusieurs projets (mêmes rapports, mêmes
repository...)
Un mécanisme d'héritage permet d'organiser et de factoriser le contenu des pom.xml
Le code à utiliser est le suivant :
< project . . . >
< parent >
< groupId > ...< / groupId >
< artifactId > ...< / artifactId >
< version > ...< / version >
< / parent >
...
< / project >
|
Via ce code, toutes les informations contenu dans le pom.xml du paquet ciblé sera
ajouté au pom.xml courant. Les informations du pom courant sont forcément
prioritaire en cas de doublons.
Attention
: On a vite tendance à mettre les repository dans un pom hérité pour alléger le pom
sur lequel on travail mais il faut toujours bien penser que le pom hérité sera
recherché sur les repository connu, il faut donc que le pom sur lequel on travail
connaisse au moins le repository où chercher son parent.
Cette solution est très intéressante pour éviter de rendre les pom illisible parce
que trop long et encore plus intéressante lorsque l'on travail sur plusieurs
projets. Il faut donc rapidement utiliser ce mécanisme et ne pas repousser sa mise
en place trop longtemps.
13. Intégration continue
13.1. Principes
Chaque développeur commit son travail sur le système de gestion de sources. Le
système d'intégration continue est connecté au système de gestion de sources va
lancer une intégration à chaque commit.
L'intégration consite alors en l'enchainement de la compilation, de l'execution
des tests unitaires, du déploiement de l'application et la génération du site de
rapports.
13.2. Bénéfices
Le mécanisme réduit les problèmes d'intégration :
Permet de s'apercevoir au plus tôt des problèmes
- Liés à l'intégration du code des différents développeurs
-
Liés à l'intégration sur une plateforme différente (OS, structure, etc.)
Souligne les éventuelles régressions
Permet une application "Snapshot" disponible en permanence
- Visibilité dans l'équipe
- Visibilité interne au département, à l'entreprise, etc.
- Visibilité au client
- Réduit l'effet tunnel
13.3. Intégration continue avec Maven
L'architecture et les principes de maven favorisent cette pratique. Le processus
de build maven est le même quel que soit l'environnement. L'utilisation des
goals Maven peut être facilement automatisées.
Plusieurs produits Open Source permettent de mettre en oeuvre une intégration
continue avec Maven :
-
CruiseControl
Le sytème historique mais vieillissant
-
Continuum
Le système proposé par Maven, intéressant mais propose moins de
fonctionnalités
-
Hudson
Le système qui a la côte en ce moment : riche et agreable d'utilisation
Le système d'intégration contninue surveille le système de gestion des sources
et lance un cycle maven complet : compilation, install, tests, déploiement,
génération du site, etc...
C'est le POM du projet qui est utilisé pour paramétrer ce cycle, la
configuration est donc la même que ce soit en local ou sur la plateforme
d'intégration.
Maven gérant également les déploiement sur des applications tel que le
déploiement d'un War dans Tomcat, avec un goal Maven supplémentaire dans
l'intégration continue, l'application peut être redéployée à chaque build.
14. Archetypes
Un Archetype est un outil pour faire des templates de projet Maven. Avec des
Archetypes existant déjà pour des grands projets tel que
Tapestry
, il est possible de créer un projet initialisé pret à compiler et déployer.
14.1. Utiliser un Archetype Maven
La commande à lancer pour créer un projet à partir d'un Archetype est presque
toujours décrite avec l'Archetype. Néammoins, la commande est la suivante :
mvn archetype:create -DarchetypeGroupId=org.apache.tapestry -DarchetypeArtifactId=quickstart
-DgroupId=org.example -DartifactId=myapp
-DpackageName=org.example.myapp -Dversion=1.0.0-SNAPSHOT
|
L'Archetype est un projet Maven identifié avec un groupId et artifactId comme
les autres. Les paramètres à renseigner correspondent donc à la localisation du
packet de l'Archetype auxquels on ajoute les paramètres du projet que l'on va
créer : son nom, les package des sources et sa version.
Cette commande va générer tout le nécessaire pour lancer un projet démo avec
Tapestry.
14.2. Créer un Archetype Maven
Un Archetype Maven est un projet Maven avec des particularités qui lui
permettront ensuite de remplacer avec les valeurs paramètrés lors du mvn
archetype:create.
15. Projets modulaires
Dans les projets Web, il est très souvent interessant de séparer le code middle du
projet de la couche de présentation. Cela permet notamment de localiser le middle
dans un jar que l'on pourra réutiliser dans le site Web mais aussi dans les batchs,
les Web Services etc...
Les projets modulaires dans Maven permettent de mettre de déclarer des métas-projets
qui sont le regroupement de plusieurs projets Maven.
15.1. Définition
Pour créer un projet multimodule, le principe est de créer plusieurs projets
Maven dans un même sous répertoire. A la racine de ce répertoire, il faut
ajouter un fichier pom.xml qui va réferencer les sous projets.
+- project/
+- pom.xml
+- sub-project1/
| +-pom.xml
+- sub-project2/
| +-pom.xml
+- sub-project3/
+-pom.xml
|
Le méta projet n'est pas obligatoirement placé à la racine des sous projets.
C'est tout de même préférable notamment pour la gestion des release comme on le
vera plus bas.
Pour référence les sous projet, le méta projet devra ressembler à ça :
< project . . . >
< modelVersion > 4.0.0< / modelVersion >
< groupId > ...< / groupId >
< artifactId > ...< / artifactId >
< packaging > pom< / packaging >
< modules >
< module > sub-project1< / module >
< module > sub-project2< / module >
< / modules >
< / project >
|
Attention pour travailler ensemble, les sous modules doivent générer leur
dépendances eux même. Par exemple, si les deux sous projets sont monProjetMiddle
et monProjetFront, il sera toujours necessaire de définir monProjetMiddle comme
dépendance de monProjetFront.
Ce n'est pas parce que plusieurs projets sont référencés dans le même
méta-projet qu'ils se connaissent les un les autres.
15.2. Utilisation
Maven propose étonnament peu de fonctionnalité qui se basent directement sur le
mécanisme des modules. La seule fonctionnalité directe est le "reactor". Le
"reactor" est le mecanisme qui fait que lorsqu'on lance un goal sur un
méta-projet, ce goal va d'abord être lancé successivement sur tous les
sous-projets.
...
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Summary:
[INFO] ------------------------------------------------------------------------
[INFO] sub project 1 .......................................... SUCCESS [12.892s]
[INFO] sub project 2 .......................................... SUCCESS [15.000s]
[INFO] sub project 3 .......................................... SUCCESS [0.313s]
...
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 1 minute 32 seconds
[INFO] Finished at: Tue Jul 08 17:19:38 CEST 2008
[INFO] Final Memory: 15M/33M
[INFO] ------------------------------------------------------------------------
|
Dans la définition des goals Maven, il est possible de traiter le fait de
s'executer ou non dans le cadre d'un projet multi-module. Il est donc possible
de trouver des plugin Maven qui ont un comportement particulier pour les projets
multi-modules, c'est le cas notamment pour le plugin Maven pour Lutèce.
15.3. Intérêts et développements
On l'a vu, Maven propose peu de fonctionnalités directement liées aux
modules, pourtant l'utilisation en est de plus en plus importante.
En effet un des intétrêts majeur de Maven est sa gestion fine des
dépendances. Il est de plus en plus souvent interessant de profiter de cette
gestion au sein même d'un projet.
Comme on l'a vu, dans un projet Web, on va rapidement extraire le middle
dans un projet à part afin de pouvoir en dépendre depuis plusieurs projet
differents.
Dans les grands framework, ce besoin est encore plus évident : pour les
projets volumineux comme Spring, de ne pas avoir tout en dépendance. Par
exemple, si on utilise pas la fonctionnalité de connexion au LDAP de Spring,
il n'est pas nécessaire de dépendandre de l'artefact spring-ldap ni des
dépendances nécessaire à la connexion LDAP etc...
Spring est aujourd'hui découpé en plus de 40 modules, Hibernate, Tapestry,
Struts sont déjà tous des projets Maven modulaires...