W3docs

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émentSignificationConvention
groupIdL'organisation ou l'espace de nomsDNS inversé, ex. com.google.code.gson
artifactIdLe nom du projet au sein du groupeMinuscules, avec tirets, ex. shop-api
versionLa version de cet artefactSémantique, ex. 1.4.0 ; -SNAPSHOT pour les builds en cours
packagingLe type de sortiejar (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.)

java— editable, runs on the server

Ce que l'on retient de l'exécution :

  • La modelVersion s'affiche comme 4.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 canonique groupId: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.
  • packaging a été lu comme jar, 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.version a é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 affichait scope=test, le maintenant hors de l'artefact livré.

Pratique

Pratique
Dans un pom.xml, quel est le but des trois éléments groupId, artifactId et version ensemble ?
Dans un pom.xml, quel est le but des trois éléments groupId, artifactId et version ensemble ?
Was this page helpful?