Java Maven pom.xml
Structure du fichier pom.xml Maven : coordonnées, propriétés et héritage du modèle objet de projet.
Le pom.xml est le cœur de tout projet Maven. POM signifie Project Object Model — un seul fichier XML qui déclare ce qu'est votre projet (son identité), ce dont il a besoin (ses dépendances) et comment le construire (plugins et configuration). Maven lit ce fichier, télécharge tout ce qu'il référence depuis un dépôt et exécute la construction. Là où un projet ad hoc disperse ces informations entre des scripts shell et un dossier lib/ de JARs copiés manuellement, Maven les regroupe toutes dans un document déclaratif et versionné.
Ce chapitre parcourt la structure du POM pièce par pièce : le squelette minimal, les coordonnées GAV qui nomment chaque artefact, le fonctionnement des dépendances et des portées, les propriétés pour dédupliquer les versions, et l'héritage via un POM parent. Si vous débutez avec Maven, commencez par l'introduction à Maven ; pour les phases de construction que le POM pilote, consultez le cycle de vie de la construction Maven.
Le POM minimal
Tout POM est un document XML enraciné dans un élément <project> avec le schéma Maven 4.0.0. Le POM utile le plus simple déclare sa version de modèle et ses coordonnées — les quatre valeurs qui nomment l'artefact :
<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>com.w3docs</groupId>
<artifactId>shop-api</artifactId>
<version>1.4.0</version>
<packaging>jar</packaging>
</project><modelVersion> est toujours 4.0.0 — c'est la version du format POM, pas de votre code. Laissez-le exactement tel qu'indiqué.
Coordonnées : groupId, artifactId, version
Un artefact Maven est identifié par ses coordonnées GAV. Chaque dépendance que vous ajoutez est nommée par les mêmes trois (parfois quatre) valeurs, il vaut donc la peine de les apprendre précisément :
| Élément | Signification | Convention |
|---|---|---|
groupId | L'organisation ou l'espace de noms | DNS inversé, ex. com.google.code.gson |
artifactId | Le nom du projet au sein du groupe | Minuscules, avec tirets, ex. shop-api |
version | La version de cet artefact | Sémantique, ex. 1.4.0 ; -SNAPSHOT pour les builds en cours |
packaging | Le type de sortie | jar (par défaut), war, pom |
Ensemble, groupId:artifactId:version est globalement unique. C'est ce que Maven utilise pour localiser un JAR dans un dépôt et pour nommer l'artefact produit par votre build. Une version se terminant par -SNAPSHOT (ex. 1.5.0-SNAPSHOT) est un build mutable en cours de développement que Maven peut re-télécharger ; une version sans ce suffixe est traitée comme immuable.
Déclarer des dépendances
Les dépendances sont listées sous <dependencies>, chacune constituant un bloc <dependency> donnant les coordonnées d'une bibliothèque dont vous avez besoin. Maven les résout — et leurs dépendances, de manière transitive — depuis un dépôt (Maven Central par défaut) :
<dependencies>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.11.0</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.10.2</version>
<scope>test</scope>
</dependency>
</dependencies>La <scope> contrôle quand une dépendance est sur le classpath. compile (la valeur par défaut) signifie partout ; test signifie uniquement lors de la compilation et de l'exécution des tests, de sorte que JUnit ne soit jamais inclus dans votre JAR. Les autres portées incluent provided (fournie par le runtime, ex. une API servlet) et runtime (nécessaire à l'exécution mais pas à la compilation, ex. un pilote JDBC). La résolution transitive, les conflits de versions et les règles de portée sont traités en détail dans les dépendances Maven.
Propriétés : ne répétez pas les versions
L'élément <properties> définit des variables réutilisables, référencées ailleurs avec la syntaxe ${name}. L'idiome consiste à figer chaque version de bibliothèque une fois en haut, de sorte que les mises à jour se fassent en un seul endroit :
<properties>
<maven.compiler.release>21</maven.compiler.release>
<junit.version>5.10.2</junit.version>
</properties>
<dependencies>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
</dependencies>maven.compiler.release est une propriété bien connue qui indique au plugin compilateur quelle version de Java cibler — plus propre que de configurer le plugin manuellement. Lorsque Maven lit le POM, il interpole chaque espace réservé ${...}, en substituant la valeur de la propriété avant toute résolution.
Héritage avec un POM parent
Les POMs forment une hiérarchie. Un élément <parent> fait hériter un projet des coordonnées, propriétés et gestion des dépendances d'un autre POM. Le parent starter de Spring Boot en est l'exemple classique — il fixe un ensemble cohérent de versions de bibliothèques afin que vous puissiez omettre <version> sur les dépendances gérées :
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.3.2</version>
</parent>
<dependencies>
<dependency>
<!-- version omitted: inherited from the parent's dependencyManagement -->
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>Un build multi-module utilise le même mécanisme en sens inverse : un POM agrégateur avec <packaging>pom</packaging> liste les <modules>, et chaque enfant le désigne comme <parent>. La configuration partagée réside en un seul endroit ; les enfants restent minuscules.
Un exemple concret : lire un POM comme Maven le ferait
Un pom.xml est simplement du XML, nous pouvons donc en analyser un avec l'API DOM intégrée du JDK et parcourir sa structure exactement comme Maven le ferait — en lisant les coordonnées, les propriétés et chaque dépendance, tout en interpolant manuellement un espace réservé ${...}. (Maven lui-même est un outil de build, pas une bibliothèque sur le classpath ici, mais cela montre le modèle sur lequel il opère.)
Ce que l'on retient de l'exécution :
- La
modelVersions'affiche comme4.0.0— la constante que tout POM porte. Elle identifie le format du POM, pas votre projet, et Maven rejetterait un POM qui l'omettrait. - Les coordonnées sont ressorties sous la forme
com.w3docs:shop-api:1.4.0, le triplet GAV dans sa forme canoniquegroupId:artifactId:version. Cette chaîne unique est la façon dont Maven nomme à la fois l'artefact produit par ce build et chaque dépendance qu'il résout. packaginga été lu commejar, le type de sortie par défaut. S'il avait étépom, il s'agirait d'un projet agrégateur/parent ne produisant aucun JAR propre.- La propriété
junit.versiona été résolue à5.10.2, et l'espace réservé${junit.version}de la dépendance JUnit a été interpolé à cette même valeur — exactement la substitution que Maven effectue pour qu'une version soit déclarée en un seul endroit et réutilisée. - Le parcours des dépendances a signalé deux dépendances et imprimé chacune avec sa portée : Gson a utilisé par défaut
compile(aucun élément<scope>, donc présent sur tous les classpaths), tandis que JUnit affichaitscope=test, le maintenant hors de l'artefact livré.