# Développer en Java/Introduction à Apache Maven
## Qu'est-ce que Maven et pourquoi faut-il l'utiliser ?

* Wikipédia propose un article sur : « Apache Maven ».
Maven 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

Au 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
### Installez Maven sur votre machine

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

Il faut télécharger la version la plus récente de Maven sur le site officiel et la dézipper.

##### Avec assistant

Un 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 :
* 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.
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 :

##### Sans assistant

Il 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

Rien n'est plus simple : utilisez votre gestionnaire de paquets.

#### Installation sous Mac OS X

avec le gestionnaire de paquets Homebrew
ou macPorts

### Configurez Maven

Dans 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

Maven utilise abondamment HTTP.

#### Utilisez une source de bibliothèques proche de chez vous
## Créez un premier projet

Maven 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

Voici 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/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 classe org.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

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

## Gérez les dépendances de votre projet

Maven 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.
Cela se fait en créant un volume et en le montant à chaque run :

### Comment trouver des bibliothèques ?

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

Si 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 :
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 »

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

## Profitez des fonctionnalités de Maven

Tout 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

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

L'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 la javadoc

La documentation sera générée dans target/site/apidocs.

#### Packager l'application

Générer un jar avec toutes les dépendances incluses. Utile pour proposer une version complète stand-alone de l'application.
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.

#### Exécuter une classe java

Si vous voulez exécutez le programme, vous pouvez faire
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.
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

À tout moment, vous pouvez vérifier la disponibilité de nouvelles versions de vos dépendances avec
Ce plug-in versions permet également de mettre à jour automatiquement les numéros de versions dans un projet.

## Pour aller plus loin
### Découvrir de nouvelles extensions

* liste des extensions sur le site officiel de Maven
* liste des extensions du projet Mojo

### Se documenter

* 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 :
** Maven by example
** Maven: The Complete Reference
** Maven Handbook
* Better Builds with Maven

## Références

* ↑ https://hub.docker.com/_/maven
* ↑ https://repository.sonatype.org/