<style>
.slides h1,
.slides h2,
.slides h3,
.slides h4,
.slides h5,
.slides h6,
h1,
h2,
h3,
h4,
h5,
h6{
color: #d35400;
}
.slides {
font-size: 3.3rem;
box-shadow: 0 0 80px #d35400;
}
.slides strong,
.slides em{
color: #FF926B;
}
.slides pre code { width: auto; max-height: initial; }
.slides code{
color: #FFBD96;
font-style: italic;
}
/* Dark theme book */
html, body, .ui-content {
background-color: #333;
color: #ddd;
}
.markdown-body h1,
.markdown-body h2,
.markdown-body h3,
.markdown-body h4,
.markdown-body h5,
.markdown-body h6 {
color: #ddd;
}
.markdown-body h1,
.markdown-body h2 {
border-bottom-color: #ffffff69;
}
.markdown-body h1 .octicon-link,
.markdown-body h2 .octicon-link,
.markdown-body h3 .octicon-link,
.markdown-body h4 .octicon-link,
.markdown-body h5 .octicon-link,
.markdown-body h6 .octicon-link {
color: #fff;
}
.markdown-body img {
background-color: transparent;
}
.ui-toc-dropdown .nav>.active:focus>a, .ui-toc-dropdown .nav>.active:hover>a, .ui-toc-dropdown .nav>.active>a {
color: white;
border-left: 2px solid white;
}
.expand-toggle:hover,
.expand-toggle:focus,
.back-to-top:hover,
.back-to-top:focus,
.go-to-bottom:hover,
.go-to-bottom:focus {
color: white;
}
.ui-toc-dropdown {
background-color: #333;
}
.ui-toc-label.btn {
background-color: #191919;
color: white;
}
.ui-toc-dropdown .nav>li>a:focus,
.ui-toc-dropdown .nav>li>a:hover {
color: white;
border-left: 1px solid white;
}
.markdown-body blockquote {
color: #bcbcbc;
}
.markdown-body table tr {
background-color: #5f5f5f;
}
.markdown-body table tr:nth-child(2n) {
background-color: #4f4f4f;
}
.markdown-body code,
.markdown-body tt {
color: #eee;
background-color: rgba(230, 230, 230, 0.36);
}
a,
.open-files-container li.selected a {
color: #5EB7E0;
}
</style>
# Maven
---
# Introduction
---
# Maven ?
- Est un outil pour la gestion et l'automatisation de production de projets logiciels
- Il cible principalement Java et en particulier les applications Java EE
---
# Motivations
### Limites de Ant
- Pas de structure *standard* de projet
- Nouveau *build.xml* à écrire pour chaque projet
- Arriver dans un nouveau projet peut-être difficile (absence de conventions)
- Que se passe-t-il si plusieurs équipes de développement utilisent des conventions différentes ?
- Pas de cycle de vie *standard* de projet
- Définition manuelle des cibles et des dépendances
- Gestion *manuelle* des bibliothèques dont dépendent le projet
- Problème de la mise à jour des versions
---
# `pom.xml` - Exemple
```xml=
<?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>fr.olprog</groupId>
<artifactId>maven_project</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<properties>
<maven.compiler.source>18</maven.compiler.source>
<maven.compiler.target>18</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
```
---
# Les principes de Maven
---
## L'approche de Maven
### Convention plutôt que configuration
- Par défaut, tous les projets se ressemblent
- Initialiser, Compiler, Tester, Assembler, ...
- Maven définit une structure de projet par défaut
- Ensemble de conventions *raisonnables*
- Il faut préciser ce qui ne suit pas les conventions
<br>
<br>
### Décrire plutôt que programmer
- Approche déclarative
- On indique les particularités du projet et non la manière de le construire
---
## Structure standard des fichiers
- `src/main/java`: sources de l'Application
- `src/main/resources`: ressources de l'Application
- `src/test/java`: sources des tests
- `src/test/resources`: sources des tests
- `src/site`: Site web
- `LICENSE.txt`
- `NOTICE.txt`
- `README.txt`
- `pom.xml`
Un plugin maven permet d'initialiser tout ceci automatiquement. On verra cela plus loin.
[Introduction to the Standard Directory Layout](https://maven.apache.org/guides/introduction/introduction-to-the-standard-directory-layout.html)
---
# `pom.xml`
---
## POM
- Project Object Model
- Fichier xml: `pom.xml`
- *modelVersion* définit le modèle de structure de projet.
- *4.0.0* est le modèle par défaut
- `pom.xml` étend en fait un fichier super-POM défini dans Maven
- On peut aussi avoir des `pom.xml` parents
- On le retrouve à la racine de l'utilisateur dans le dossier `.m2`
---
## Les sections principales
```xml=
<!-- Identifiant du groupe ayant créé le projet -->
<groupId>...</groupId>
<!-- Nom de l'artifact généré par le projet -->
<artifactId>...</artifactId>
<!-- Numéro de version de l'artifact -->
<version>...</version>
<!-- Définition de propriétés/constantes -->
<properties>...</properties>
<!-- Définition des dépendances du projet -->
<dependencies>...</dependencies>
<!-- Déclaration et configuration des plugins -->
<!-- Définition de propriétés du projet -->
<build>...</build>
```
---
## Exemple de définition de propriétés
Exemple de configuration pour le compilateur java
- Par défaut `source` et `target` sont fixés à 1.7
- Manière possible de configurer le compilateur avec une autre version
```xml=
<properties>
<maven.compiler.source>18</maven.compiler.source>
<maven.compiler.target>18</maven.compiler.target>
</properties>
```
---
# Les plugins, les tâches, les cycles de vie
---
## Les concepts de Maven
- Plugin
- Fragment de logiciel qui se spécialise dans une tâche donnée
- Ex: compilation, tests, ...
- Goals (Tâches)
- Un plugin peut exécuter un ensemble de goals (tâches unitaires)
- Ex: compile du plugin Compiler, test du plugin surefire, ...
---
## La section build
```xml=
<build>...</build>
```
- voir [Build Settings](https://maven.apache.org/pom.html#Build_Settings)
- Section permettant de déclarer des propriétés générales de votre projet
-
```xml=
<build>
<defaultGoal>install</defaultGoal>
<directory>${basedir}/target</directory>
...
</build>
```
- `defaultGoal` définit la phase par défaut à exécuter
- `directory` définit le répertoire où les fichiers générés seront stockés
----
- Déclaration et configuration de plugins
- Exemple de configuration pour le compilateur java
```xml=
<properties>
<maven.compiler.release>18</maven.compiler.release>
</properties>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.10.1</version>
</plugin>
</plugins>
</pluginManagement>
</build>
```
----
### A propos de l'exemple précédent
- Le plugin de compilation Java par défaut n'est pas compatible avec les versions récentes de Java (>= 9)
- L'exemple précédent charge une version plus récente du plugin
- La propriété `<maven.compiler.release>` remplace les propriétés `<maven.compiler.source>` et `<maven.compiler.target>`
[maven-compiler-plugin](https://maven.apache.org/plugins/maven-compiler-plugin/)
---
## Cycle de vie
Pour identifier et enchaîner les tâches de base dans un projet, Maven se base sur :
- Les plugins et les tâches associées
- Un cycle de vie
### Cycle de vie
- Série de phases ordonnées
- Définit les étapes clés de la construction du projet
- 3 cycles de vie prédéfinis:
- `default`: *construire* votre projet
- `clean`: *nettoyage* du projet
- `site`: création de la documentation du projet
---
## Cycle de vie par défaut
Les phases principales du cycle de vie par défaut:
- `validate`: valide que le projet est correct et que toutes les infos nécessaires sont disponibles
- `compile`
- `test`
- `package`: package les source compilées dans un format distribuable (par ex : *JAR*)
- `integration-test`
- `verify`: Lance les test pour vérifier la qualité du package
- `install`: Installe le package dans le dépôt local
- `deploy`: Copie le package final dans un dépôt distant pour le partager
[Pour une liste complète](http://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html)
----
Demander l'exécution d'une phase d'un cycle entraîne l'exécution de toutes les phases précédentes
- `mvn deploy`: Exécute toutes les phases du cycle par défaut
- `mvn clean install`: Exécute la phase `clean` (et précedentes) puis install (et précédentes)
### Qu'est ce qui est exécuté par une phase ?
- Les tâches qui lui ont été associées
---
## Associer des tâches à des phases
- Définir le packaging de son projet
- `<packaging>jar</packaging>`
- Le packaging associe des tâches aux phases du cycle par défaut
- Le packaging par défaut est *jar* (autres: ejb, ear, war, ...)
----
Tâches associées par le packaging *jar*:
| phase | tâche |
|:---------------------- |:----------------------- |
| process-resources | resources:resources |
| compile | compiler:compile |
| process-test-resources | resources:testResources |
| test-compile | compiler:testCompile |
| test | surefire:test |
| package | jar:jar |
| install | install:install |
| deploy | deploy:deploy |
---
## Associer une tâche d’un plugin à une phase
```xml=
...
<plugin>
<groupId>com.mycompany.example</groupId>
<artifactId>display-maven-plugin</artifactId>
<version>1.0</version>
<executions>
<execution>
<phase>test</phase>
<goals>
<goal>time</goal>
</goals>
</execution>
</executions>
</plugin>
...
```
- La tâche `display:time` sera executée dans la phase test
- Ordre d’exécution des tâches:
- Celles définies par le packaging en premier
- Puis exécution selon l’ordre d’apparition dans le POM
---
# Coordonnées, dépôts et dépendances
---
## En 2 mots
- Chaque projet est identifié de manière unique
- Coordonnées
- Les *artifacts* d'un projet peuvent être publiés vers un dépôt maven
- Local ou distant
- Les *artifacts* nécessaires à un projet (dépendances) sont téléchargés automatiquement par maven
- Gestion automatique des dépendances transitives
---
## Coordinates (coordonnées)
- Le fichier POM fournit un ensemble d'identifiants uniques du projet :
```xml=
<groupId>fr.olprog</groupId>
<artifactId>maven_project</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
```
- `groupId`: identifie l'entité qui gère le projet
- `artifactId`: identifie le projet
- `version`: numéro de version du projet
- *SNAPSHOT*: Mot clé indiquant à Maven que le projet est en cours de développement
----
- Les dépôts maven (publics, privés, locaux) sont organisés autour de ces coordonnées
- Lorsque qu'un projet est *installé* localement, il devient disponible pour tout autre projet
- Il suffit de déclarer une dépendance en utilisant les coordonnées de l'*artifact*
---
## Les dépôts Maven
- Un dépôt Maven stocke des *artifacts*:
- Stocke un ensemble d'*artifacts* de projet rangés selon une structure de répertoires correspondant aux coordonnées Maven
- Dépôt distant par défaut : [Dépôt Maven](https://repo.maven.apache.org/maven2/)
- Dépôt local par défaut: `$HOME/.m2/repository`
- Possibilité d'ajouter des dépôts
- Possibilité de créer des dépôts privés
----
- Les plugins et dépendances sont obtenues depuis les dépôts
- Si un *articfact* n'est pas dans le dépôt local, recherche dans le dépôt distant
- Stockage dans le dépôt local pour résolution locale lors du prochain appel
- Attention: Grand nombre de téléchargements lors des premières utilisations
- `mvn install` install le projet dans le dépôt local
- Si un *artifact* a le tag *SNAPSHOT*, vérification à chaque appel qu'une version plus récente n'est pas disponible sur le dépôt distant.
---
## Les dépendances
```xml=
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
</dependencies>
```
- Définition des dépendances dans la section `dependencies`
- Maven gère les dépendances transitives
- Les dépendances ont une portée (scope)
---
## Résolution transitive des dépendances
A chaque *artifact* est associé un fichier `pom.xml` dans lequel est défini ses dépendances
- Si mon projet dépend de *A* et que *A* dépend de *B*, mon projet dépend de *B*
- Maven installera automatiquement *B*
### Remarques en plus
- Médiation si conflit entre dépendances (*nearest definition*)
- Contrôle de la version des dépendances transitives par déclaration explicite
- Utilisation de la balise `<exclusion>` pour exclure des dépendances
---
## Portée des dépendances
Chaque dépendance a une portée (`<scope>`):
- Permet de couper l'arbre des dépendances
- Influence le `classpath` utilisé dans chaque phase
----
6 portées possible:
- `compile` (portée par défaut)
- Disponible dans tous les `classpaths`
- Dépendances propagées aux projets dépendants (transivité)
- `provided`
- `Classpath` pour la compilation et les tests
- Pas de transivité
- Dépendance résolue pour la compilation et le test mais supposée déjà disponible dans le contexte d'exécution
- `runtime`
- `Classpath` pour les test et au runtime
----
- `test`
- `Classpath` pour la compilation et l'exécution des tests
- `system`
- Similaire à `provided`
- La dépendance doit être fournie (pas de résolution par les dépôts)
- `import`
- utilisé dans le contexte de la balise `<dependencyManegement>`
Chaque scope affecte les dépendances transitives de manière différente.
[mécanisme de dépendance](https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html)
---
## A propos des dépendances et des dépôts
Simplification de la gestion des bibliothèques:
- Automatisation de la gestion des dépendances
- Vérification de l'intégralité des bibliothèques téléchargées (hachage)
- Niveau de confuance dans les bibliothèques fournies par un dépôt public
---
# Des infos en plus
---
## Hiérarchie de projets : Héritage
- Utilisation: Factorisation de plusieurs projets avec des configurations similaires
- Définition d'un *POM* parent
- Modèle objet: un *POM* hérite des attributs de son parent sauf si il les redéfinit
- Les dépendances
- Les plugins
- Configuration des plugins
- ...
- Arborescence de fichiers
- `pom.xml` (parent)
- `my-module/pom.xml`
[Héritage de projet vs. Agrégation de projet](https://maven.apache.org/guides/introduction/introduction-to-the-pom.html#Project_Inheritance_vs_Project_Aggregation)
---
## Exemple d'héritage
`pom.xml`
```xml=
<project>
<parent>
<groupId>fr.olprog.app</groupId>
<artifactId>my-app</artifactId>
<version>0.0.1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>my-module</artifactId>
</project>
```
`pom.xml` du parent
```xml=
<project>
<groupId>fr.olprog.app</groupId>
<artifactId>my-app</artifactId>
<version>0.0.1</version>
<modelVersion>4.0.0</modelVersion>
</project>
```
---
## Hiérarchie de projets: Agrégation
- Utilisation: Regrouper un ensemble de projets à construire ensemble
- Définition d'un *POM* connaissant un ensemble des modules
- Quand une commande est exécutée sur le *POM* parent, elle est aussi exécutée sur les modules du parent
- Le *POM* parent doit avoir le `packaging pom`
- Peut-être combiné avec de l'héritage
- Arborescence de fichiers
- `pom.xml` (parent)
- `my-module/pom.xml`
---
## Exemple d'agrégation
DevOps - Maven
`pom.xml`
```xml=
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>fr.olprog.app</groupId>
<artifactId>my-module</artifactId>
<version>0.0.1</version>
</project>
```
`pom.xml` du parent
```xml=
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>fr.olprog.app</groupId>
<artifactId>my-app</artifactId>
<version>1</version>
<packaging>pom</packaging>
<modules>
<module>my-module</module>
</modules>
</project>
```
---
## Création d'un projet
### Plugin `archetype`
- Permet à l'utilisateur de créer un projet à partir d'un template
- Création du projet pour une interrogation à la BDD
- `mvn archetype:generate -DgroupId=fr.olprog.app -DartifactId=my-bdd-app -DarchetypeArtifactId=maven-archetype-quickstart`
- `archetype` est l'identifiant du `plugin`
- `generate` est l'identifiant du `goal`
- Exemple de passage de paramètres au plugin via la ligne de commande
- sans l'option `maven-archetype-quickstart`, Maven nous aurait demandé quel type de projet créer
----
Ajouter les properties si ce n'est pas le cas:
```xml
<properties>
<maven.compiler.target>17</maven.compiler.target>
<maven.compiler.source>17</maven.compiler.source>
</properties>
```
Puis testez la compilation:
```bash=
mvn compile
```
Puis vérifiez les tests unitaires:
```bash=
mvn test
```
Puis lancez le programme:
```bash=
mvn exec:java -Dexec.mainClass=fr.olprog.app.App
```
---
## Quelques détails en plus
- Afficher un fichier *POM* complet (utile pour le debug)
- `mvn help:effective-pom`
- Afficher la liste des tâches d'un plugin
- `mvn help:describe -Dplugin=pluginName`
- Afficher la liste des paramètres d'une tâche
- `mvn help:describe -Dcmd=pluginName:goal -Ddetail`
---
# Conclusion
---
## Résumé
**Maven**, c'est:
- convention plutôt que configuration
- Décrire plutôt que programmer
**Plus précisément**:
- Un identifiant unique de projet (sous forme de *Coordonnées*)
- Un *cycle de vie* par défaut (qui définit des phases)
- Un *packaging de projet* qui définit les tâches par défaut associés à chaque phase
- Des *plugins* qui peuvent exécuter une ou plusieurs tâches
- Ces tâches peuvent être associés à des phases du cycle de vie
- Des *dépendances* (artifacts)
- Qui sont gérées automatiquement (au travers de *dépôts* publiques ou privés), tout comme les plugins
- Qui peuvent être associées à certaines phases
---
## Une alternative à Maven : Gradle
### Existant:
- Ant: Flexible mais nécessite une description complète de projet
- Maven: "Convention plutôt que configuration" mais manque de flexibilité
### Gradle
- Vise à combine le meilleur des 2 mondes
- Principe de bases similaires à Maven
- Cycle de vie
- Plugins
- Dépendances
- Utilise une DSL (Groovy) à la place du xml
- Permet d'inclure du code pour mettre en oeuvre de nouvelles fonctionalités.
---
## Références
- Notes de D. Donsez
- Apache Maven par N. De Loof et A. Héritier
- Traduction française de "Maven: The Definitive Guide"
- [Documentation de Maven](https://maven.apache.org/guides/index.html)
- A practical guide to continuous delivery par E. Wolff
- [Maven in 5 minutes](https://maven.apache.org/guides/getting-started/maven-in-five-minutes.html)
- [Maven getting started guide](https://maven.apache.org/guides/getting-started/index.html)
{"metaMigratedAt":"2023-06-17T10:53:41.698Z","metaMigratedFrom":"YAML","title":"Maven","breaks":false,"description":"Formation Maven","robots":"noindex, nofollow","slideOptions":"{\"transition\":\"slide\",\"slideNumber\":true,\"previewLinks\":true,\"overview\":true,\"width\":1366,\"height\":768}","contributors":"[{\"id\":\"35198f6d-8c66-4636-8d98-b19eb0b4c48c\",\"add\":20464,\"del\":419}]"}