<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}]"}
    83 views