Développer en Java/Introduction à Apache Maven
Qu'est-ce que Maven et pourquoi faut-il l'utiliser ?
modifierMaven permet de faciliter et d'automatiser certaines tâches de la gestion d'un projet Java. Il permet notamment :
- d'automatiser certaines tâches : compilation, tests unitaires et déploiement des applications qui composent le projet ;
- de gérer des dépendances vis à vis des bibliothèques nécessaires au projet ;
- de générer des documentations concernant le projet.
Pour gérer les dépendances du projet vis à vis de bibliothèques, Maven utilise un ou plusieurs dépôts (appelés repositories) qui peuvent être locaux (.maven/repository) ou distants (http://www.ibiblio.org/maven par défaut)
Maven est extensible grâce à un mécanisme d'extension qui permet d'ajouter des fonctionnalités.
Maven comparé à Ant
modifierAu premier abord, il est facile de croire que Maven fait double emploi avec Ant. Ant et Maven sont tous les deux développés par le groupe Jakarta, ce qui prouve bien que leur utilité n'est pas aussi identique. Ant dont le but est d'automatiser certaines tâches répétitives est plus ancien que Maven. Maven propose non seulement ces fonctionnalités mais en propose de nombreuses autres.
Mettre en place Maven
modifierInstallez Maven sur votre machine
modifierIci, la procédure diffère selon le système d'exploitation que vous utilisez. L'installation sous Linux est extrêmement simple, l'installation sous Windows l'est moins.
Installation sous Windows
modifierIl faut télécharger la version la plus récente de Maven sur le site officiel et la dézipper.
Avec assistant
modifierUn assistant permet de fournir les informations concernant l'installation :
- sur la page « Licence Agreement » : lire la licence et si vous l'acceptez cliquer sur le bouton « I Agree ».
- sur la page « Installations Options » : sélectionner les éléments à installer et cliquer sur le bouton « Next ».
- sur la page « Installation Folder » : sélectionner le répertoire dans lequel Maven va être installé et cliquer sur le bouton « Install ». Par défaut, sous Windows :
C:\Program Files\Apache Software Foundation\maven-2.0.3
- une fois les fichiers copiés, il suffit de cliquer sur le bouton « Close ».
Un élément de menu nommé « Apache Software Foundation / Maven --version » est ajouté dans le menu « Démarrer / Programmes ».
Pour utiliser Maven, la variable d'environnement système nommée MAVEN_HOME doit être définie avec comme valeur le chemin absolu du répertoire dans lequel Maven est installé. Par défaut, cette variable est configurée automatiquement lors de l'installation sous Windows.
C:\Program Files\Apache Software Foundation\maven-2.0.3\bin";%PATH%
Il est aussi particulièrement pratique d'ajouter le répertoire %MAVEN_HOME%/bin à la variable d'environnement PATH. Maven étant un outil en ligne de commande, cela évite d'avoir à saisir son chemin complet lors de son exécution.
Il faut s'assurer également que le JDK est installé. Le répertoire par défaut sous Windows est C:\Program Files\Java\jdkn° de version
(Exemple: C:\Program Files\Java\jdk1.5.0_14
).
Enfin, il faut créer un repository local en utilisant la commande ci dessous dans une boîte de commandes DOS :
C:\>install_repo.bat %HOMEDRIVE%%HOMEPATH%
Sans assistant
modifierIl suffit de placer les fichiers dans un répertoire qui sera spécifié dans la variable d'environnement M2_HOME.
Ensuite, définir les variables d'environnement correspondantes, par exemple :
- JAVA_HOME = C:\Program Files\Java\jdk1.7.0_03\
- M2_HOME = C:\Program Files\Java\apache-maven-3.0.4\
- path = C:\Program Files\Java\apache-maven-3.0.4\bin
Installation sous GNU/Linux
modifierRien n'est plus simple : utilisez votre gestionnaire de paquets.
Installation sous Mac OS X
modifieravec le gestionnaire de paquets Homebrew
$ brew install maven
ou macPorts
$ sudo port install maven3
Testez votre installation
modifier$ mvn --version
Configurez Maven
modifierDans votre répertoire personnel, vous trouverez un dossier « .m2 » contenant un fichier « settings.xml » qui va vous permettre de configurer Maven.
Si vous êtes derrière un proxy réseau
modifierMaven utilise abondamment HTTP.
Utilisez une source de bibliothèques proche de chez vous
modifierCréez un premier projet
modifierMaven se base sur les conventions pour trouver tous les composants de vos projets, suivez-les et Maven se débrouillera sans aucune configuration.
Arborescence d'un projet Maven
modifierVoici l'arborescence minimum d'un projet Maven.
mon_projet
- un dossier qui va contenir toutes les données du projet
mon_projet/src
- ce dossier va contenir tous les fichiers sources créés par les développeurs pour le projet
mon_projet/src/main
mon_projet/src/main/java
- contient les codes sources Java, rangés selon le hiérarchie des packages. (par exemple,
mon_projet/src/main/java/org/wikibooks/fr/Exemple.java
pour la classeorg.wikibooks.fr.Exemple
) mon_projet/src/main/resources
- les ressources nécessaires au code Java. Fichiers de configuration, icônes, fichiers de données...
mon_projet/src/test
- contient toutes les données nécessaire pour tester l'application
mon_projet/src/test/java
- contient les codes sources des tests
mon_projet/src/test/resources
- les ressources qui sont utilisées dans les tests
mon_projet/pom.xml
- un fichier XML qui décrit le projet pour permettre à Maven d'interagir avec lui.
Le « Project Object Model » : fichier pom.xml
modifierTous les projets Maven sont identifiés de façon unique. Pour cela, un projet est identifié par 3 valeurs :
- Un groupId
- Il désigne l'organisation responsable de ce projet. Il arrive souvent qu'on suive les conventions sur les noms de package pour définir le groupId. Votre groupId doit être propre à votre organisation et être composé d'un nom de domaine dont vous avez le contrôle pour être sûr qu'aucun autre projet qui n'est pas de vous ne porte le même groupId. Bon exemple, si vous travaillez dans une entreprise, utilisez le nom de domaine de votre entreprise (
com.maboite
), si vous êtes étudiants, utilisez le domaine de votre formation (fr.monuniversite.moncours
), si c'est un logiciel libre, utilisez l'adresse du site du projet ou de la forge, etc. - Un artifactId
- Il identifie le projet lui même : pour faire simple, c'est le nom que portera le fichier
.jar
qui sera généré par la construction du projet. Il faut donc veiller à ce que son nom soit sans ambigüité. Bons exemples : junit, commons-io, http-client ; mauvais exemples : test, core, module. - Une version
- Pour finir d'identifier une application ou une bibliothèque, on ajoute une troisième composante, la
version
.
Commençons par un pom minimal :
<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/maven-v4_0_0.xsd">
<!-- Toujours utiliser 4.0.0 pour maven 2.x -->
<modelVersion>4.0.0</modelVersion>
<!-- groupId, artifactId et version actuelle -->
<groupId>org.wikibooks.fr</groupId>
<artifactId>projet-minimal</artifactId>
<version>1.0</version>
<!-- la façon dont sera packagée l'application -->
<packaging>jar</packaging>
<!-- un nom pour le projet -->
<name>Un projet d'exemple pour le livre Développer en Java de Wikibooks</name>
<!-- l'adresse du site qui présente cette application -->
<url>http://fr.wikibooks.org/wiki/Développer_en_Java/Introduction_à_Apache_Maven</url>
</project>
Gérez les dépendances de votre projet
modifierMaven gère toutes les dépendances de vos projets. Pour cela, il stocke toutes les bibliothèques de vos projets dans un dépôt local situé "~/.m2/repository". À chaque fois que vous demanderez à Maven de construire le projet, Maven ira chercher toutes les dépendances dans votre dépôt local. Si Maven ne trouve pas la dépendance dans votre dépôt local, il ira automatiquement la télécharger depuis un dépôt sur Internet et l'ajoutera à votre dépôt local. Au début, votre dépôt est vide, donc Maven téléchargera beaucoup de choses lors des premières utilisations.
Votre dépôt local est bien rangé, Maven organise tout et range toutes les bibliothèques selon le groupId, l'artifactId et les versions. À tout moment, vous pouvez supprimer l'intégralité de votre dépôt local pour faire le ménage. Maven ne re-téléchargera que le nécessaire.
Sur le docker, il faut partager le repo local du conteneur avec la machine hôte, sous peine de tout télécharger à chaque compilation[1].
Cela se fait en créant un volume et en le montant à chaque run :
docker volume create --name maven-repo
docker run -it -v maven-repo:/root/.m2 maven mvn archetype:generate
Comment trouver des bibliothèques ?
modifierLorsque Maven cherche une dépendance sur Internet, il s'oriente vers un dépôt principal où se trouvent l'essentiel des bibliothèques Java disponibles et qui s'appelle « central ». Et l'application en ligne Nexus permet de parcourir son contenu et de faire des recherches par groupId, artifactId et version[2]. Une fois que vous avez trouvé la bibliothèque qui remplit vos besoin, l'application peut vous donner le petit code XML à ajouter au POM du projet.
Déclarer une dépendance
modifierSi votre application a besoin d'une dépendance, c'est simple, il suffit d'ajouter au POM la dépendance : son groupId, artifactId et version. Par exemple, pour que les développeurs bénéficient de l'API commons lang, il suffit d'ajouter dans le POM :
<!-- ... -->
<dependencies>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.5</version>
</dependency>
</dependencies>
Pour compiler ou lancer le projet, Maven ira chercher la dépendance dans le dépôt local, ou sur Internet si besoin.
Les différents « scope »
modifierUne dépendance a une portée (scope), c'est à dire qu'elle est utilisée pour certaines tâches. Il existe les portées (scopes) suivantes :
compile
- c'est le scope par défaut. La dépendance est utilisée pour compiler le code et est nécessaire à son exécution. Lorsque l'application sera construite par Maven, cette dépendance sera ajoutée dans le fichier jar généré.
test
- cette dépendance est nécessaire seulement pour la compilation et l'exécution des tests. Quand Maven construira l'application, il n'ajoutera pas cette dépendance au jar généré étant donné que cette bibliothèque n'est pas utilisée dans l'application principale mais seulement dans les tests (remarque : les tests bénéficient, eux, des dépendances
compile
). runtime
- la dépendance n'est pas disponible à la compilation mais est fournie au lancement de l'application. Par exemple, un pilote de base de données (JDBC).
provided
- la dépendance ne sera pas jointe à l'application mais sera fournie quand elle sera déployée. Par exemple, une application peut dépendre d'un élément qui ne lui sera fourni que lorsqu'elle sera déployée dans le serveur d'application. Comme il y a plusieurs serveurs d'application différents, on confie à ce dernier le soin de fournir la dépendance.
Par la suite, nous aurons l'usage des ces différents scopes.
Un POM d'exemple complet
modifier<?xml version="1.0" encoding="UTF-8"?>
<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, artifactId et version actuelle -->
<groupId>org.wikibooks.fr</groupId>
<artifactId>projet-minimal</artifactId>
<version>1.0</version>
<!-- la façon dont sera packagée l'application -->
<packaging>jar</packaging>
<!-- un nom pour le projet -->
<name>Un projet d'exemple pour le livre Développer en Java de Wikibooks</name>
<!-- l'adresse du site qui présente cette application -->
<url>http://fr.wikibooks.org/wiki/Développer_en_Java/Introduction_à_Apache_Maven</url>
<dependencies>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.1.1</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.16</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>1.4</version>
</dependency>
<!-- test -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
<properties>
</properties>
<build>
</build>
</project>
Profitez des fonctionnalités de Maven
modifierTout est en place, le projet est prêt. On peut maintenant passer à l'action et profiter des nombreuses possibilités offertes par Maven.
Construire le projet
modifierLa construction d'un projet se passe en différentes phases successives qui décrivent le cycle de vie (Build Lifecycle) :
validate
- vérifie que le POM est correct et complet
compile
- compile les sources du projet qui se trouvent dans src/main/java et place les fichiers compilés (.class) dans target
test
- compile les tests qui se trouvent dans src/test/java et lance l'intégralité des tests, les tests compilés sont placés dans target
package
- génère un package de l'application dans target/artifactId-version.jar
install
- utilise le package généré à la phase
package
et l'ajoute au dépôt local. À utiliser pour une bibliothèque : elle peut dès lors être utilisée comme dépendance pour un autre projet. deploy
- déploie l'application (varie selon la configuration)
Une autre phase est :
clean
- détruit le répertoire target
Voici quelques exemples d'utilisation :
# on peut lancer une phase avec mvn phase, par exemple
mvn compile # exécute la phase validate puis la phase compile
mvn package # fait appel à toutes les phases précédentes
# on peut donner plusieurs phases en paramètres, par exemple
mvn clean test # exécute la phase clean puis la phase test
# Enfin, quel que soit la phase, on peut demander à Maven de sauter les tests, pour gagner du temps
mvn install -Dmaven.test.skip # saute la compilation et l'exécution des tests
# ou
mvn install -DskipTests # compile les tests mais saute l'exécution
Il y a d'autres phases intermédiaires mais nous avons choisi de ne vous présenter que celles qui sont utilisées 80% du temps.
Exploiter les nombreuses possibilités offertes par les extensions Maven
modifierL'outil mvn
peut faire appel à des extensions. Chaque extension est proposée avec un ensemble d'actions possibles appelées goal
. On utilise alors mvn extension:goal
.
Pour la plupart des extensions, il existe un goal help
. Par exemple, mvn javadoc:help
devrait donner l'aide pour l'extension javadoc et tous les goals que propose cette extension.
Générer un site internet pour le projet
modifiermvn site:site
Générer la javadoc
modifierLa documentation sera générée dans target/site/apidocs.
mvn javadoc:javadoc
Packager l'application
modifierGénérer un jar avec toutes les dépendances incluses. Utile pour proposer une version complète stand-alone de l'application.
mvn assembly:assembly -DdescriptorId=jar-with-dependencies
Générer un jar avec seulement les sources, idéal pour distribuer le code à des développeurs pour qu'ils l'intègrent à leur IDE.
mvn assembly:assembly -DdescriptorId=src
Exécuter une classe java
modifierSi vous voulez exécutez le programme, vous pouvez faire
mvn package
cd target
java -jar mon-artifact.jar
Cela ne fonctionnera pas étant donné qu'il faut ajouter au CLASSPATH tout un tas de fichier jar qui se trouvent dans votre dépôt local. La plug-in exec vous permet d'exécuter un programme principal.
mvn exec:java -Dexec.mainClass=org.wikibooks.fr.ClassePrincipale -Dexec.args="argument1 argument2"
# attention : -Dexec.args="" passe l'argument "" (chaîne vide) à l'application
On peut aussi ajouter les informations sur le nom de la classe principale, les arguments et les réglages systèmes dans le POM.
Surveiller les mises à jours des dépendances
modifierÀ tout moment, vous pouvez vérifier la disponibilité de nouvelles versions de vos dépendances avec
mvn versions:display-dependency-updates
[INFO] [versions:display-dependency-updates {execution: default-cli}] [INFO] The following dependencies in Dependency Management are using the newest version: [INFO] commons-daemon:commons-daemon .................................. 1.0.1 [INFO] commons-io:commons-io ............................................ 1.4 [INFO] commons-lang:commons-lang ........................................ 2.5 [INFO] commons-logging:commons-logging ................................ 1.1.1 [INFO] junit:junit .................................................... 4.8.1 [INFO] log4j:log4j ................................................... 1.2.16 [INFO] [INFO] The following dependencies in Dependency Management have newer versions: [INFO] org.mortbay.jetty:jetty .............................. 6.1.9 -> 6.1.25 [INFO] org.quartz-scheduler:quartz ........................... 1.8.3 -> 1.8.4
Ce plug-in versions permet également de mettre à jour automatiquement les numéros de versions dans un projet.
Pour aller plus loin
modifierDécouvrir de nouvelles extensions
modifierUtiliser les profils
modifierSe documenter
modifier- La première source d'informations reste le site officiel.
- Sonatype, qui travaille beaucoup sur le développement de Maven, propose plusieurs livres en ligne et en anglais :
- Better Builds with Maven