IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)

Utilser Maven 2

Date de publication : 04/08/2008 , Date de mise à jour : 04/08/2008

Par Matthieu Lux (Tous les articles)
 

synopsis

               Version PDF   Version hors-ligne

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.

info La philosophie de Maven

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.

info Les bases du pom.xml

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
info La structure des fichiers par défaut

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 :

	mvn <nom du goal>
					
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>
					
info 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 :

	mvn compile
				
ou

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

Le plus judicieux est de toujours se référer à la page de rapport du plugin pour savoir quels paramètres peuvent lui être précisés. Pour trouver un plugin maven, la recherche Google "maven <nom du plugin> plugin" répondra pratiquement toujours.

Vous trouverez ensuite toujours sur le site du plugin la page : "Project Reports/Plugin documentation" . Il s'agit d'un rapport automatique de Maven.

info La page d'accueil listera toujours les goal du plugin.
Cliquer sur un goal proposera la liste des paramètres qui peuvent lui être passés.

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.

info Gestion des dépendances

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 :

	mvn 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>
				
info Gestion des resources

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 :

	mvn package
			
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.

	mvn eclipse:eclipse
			
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.

info Maven Eclipse Plugin

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

	mvn eclipse:m2eclipse
				
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
info m2Eclipse

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.

info q4e

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 :

mvn site
			
(ou)

mvn site:site
			
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

info Les bases de la gestion du site Maven sont décrit ici.
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 :


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.

info Introduction aux Archetypes Maven

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.

Pour les détails concernant la création d'un Archetype Maven, il y a deux sources principales : Créer son propre Archetype Maven sur le site Maven et le site du plugin Archetype


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



               Version PDF   Version hors-ligne

Valid XHTML 1.1!Valid CSS!