Spécifier la version Java dans Maven : properties vs maven-compiler-plugin

Fixer la version Java d'un projet Maven peut se faire de trois manières qui coexistent dans les POM qu'on trouve sur GitHub : via des propriétés, via le maven-compiler-plugin, ou via la nouvelle propriété release. Elles ne sont pas équivalentes.

Méthode 1 — propriétés Maven (la plus courante)

<properties>
  <maven.compiler.source>21</maven.compiler.source>
  <maven.compiler.target>21</maven.compiler.target>
</properties>

Maven lit ces deux propriétés automatiquement quand le maven-compiler-plugin tourne. source définit la syntaxe du langage acceptée, target la version du bytecode généré.

Méthode 2 — configuration explicite du plugin

<build>
  <plugins>
    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-compiler-plugin</artifactId>
      <version>3.13.0</version>
      <configuration>
        <source>21</source>
        <target>21</target>
      </configuration>
    </plugin>
  </plugins>
</build>

Plus verbeux mais permet de passer d'autres options (<compilerArgs>, <encoding>, annotation processors). Si les deux méthodes sont présentes, la configuration du plugin l'emporte sur les propriétés.

Méthode 3 — release (Java 9+)

<properties>
  <maven.compiler.release>21</maven.compiler.release>
</properties>

Introduite en Java 9 (flag --release), cette option est la meilleure. Elle fixe simultanément source et target, et restreint l'accès aux APIs du JDK à celles disponibles dans cette version. Avec source=21 + target=8, vous pouviez accidentellement appeler une méthode Java 21 puis la compiler en bytecode Java 8 — erreur détectée seulement au runtime. Avec release, le compilateur rejette ces appels à la compilation.

Laquelle utiliser ?

  1. Java 9+ : maven.compiler.release exclusivement.
  2. Java 8 uniquement : maven.compiler.source + target (l'option release n'existait pas).
  3. N'utilisez la configuration explicite du plugin que si vous avez besoin de compilerArgs ou d'annotation processors.

Attention à la JVM qui exécute Maven

Maven ne peut pas compiler pour une version de Java supérieure à celle du JDK qui exécute Maven lui-même. Si mvn -version affiche Java 17, vous ne pouvez pas cibler Java 21 dans le POM. Mettez à jour votre JDK ou utilisez la fonctionnalité toolchains de Maven pour pointer vers un autre JDK installé.

Exemple complet recommandé

<project>
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.example</groupId>
  <artifactId>app</artifactId>
  <version>1.0.0</version>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.release>21</maven.compiler.release>
  </properties>
</project>

Deux lignes suffisent pour un projet moderne. Le reste — plugin explicite, source/target dupliqués — ne sert qu'à gérer des cas particuliers.