Spécification de la version java dans maven-différences entre les propriétés et le plugin du compilateur


Je ne suis pas très expérimenté avec maven et en expérimentant avec un projet multi-modules, j'ai commencé à me demander comment puis-je spécifier la version java pour tous mes modules enfants dans maven pom parent. Jusqu'à aujourd'hui, j'utilisais juste:

<properties>
    <java.version>1.8</java.version>
</properties>

Mais lors de mes recherches, j'ai trouvé que vous pouvez également spécifier la version java dans le plugin maven compiler, comme ça:

<plugins>
    <plugin>    
        <artifactId>maven-compiler-plugin</artifactId>
        <configuration>
            <source>1.8</source>
            <target>1.8</target>
        </configuration>
    </plugin>
</plugins>

Puis enveloppez-le dans la balise de gestion du plugin pour activer l'utilisation de poms enfants. Donc, la première question est quels sont les différences beetwen définissant la version java dans les propriétés et dans le plugin du compilateur maven?

Je n'ai pas pu trouver de réponse claire mais en cours de recherche, j'ai trouvé que vous pouvez également spécifier la version java de cette façon:

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

Ce qui suggère que le plugin du compilateur est là même si je ne le déclare pas explicitement. Exécution des sorties du package mvn avec

maven-compiler-plugin:3.1:compile (default-compile) @ testproj ---

Et d'autres plugins que je n'ai pas déclarés. Donc, ces plugins sont-ils par défaut, une partie cachée de maven pom? Il n'existe aucun différences beetwen définissant la source / cible dans les propriétés et dans l'élément de configuration du plugin maven?

D'autres questions sont-quelle manière devrait être utilisée (et quand si elles ne sont pas égales)? Lequel est le meilleur pour le projet multi-modules et que se passe-t-il si la version java spécifiée dans pom est différente de la version pointée dans JAVA_HOME?

Author: Gray, 2016-08-10

2 answers

Comment spécifier la version JDK?

1) <java.version> n'est pas référencé dans la documentation Maven.
C'est une spécificité de botte de printemps.
Il permet de définir la version source et la version cible de java avec la même version telle que celle-ci pour spécifier java 1.8 pour les deux:

<properties>
     <java.version>1.8</java.version>
</properties>   

N'hésitez pas à l'utiliser si vous utilisez Spring Boot.

2) à l'Aide de maven-compiler-plugin ou maven.compiler.source/maven.compiler.target propriétés pour spécifier le source et le target sont équivalents.

<plugins>
    <plugin>    
        <artifactId>maven-compiler-plugin</artifactId>
        <configuration>
            <source>1.8</source>
            <target>1.8</target>
        </configuration>
    </plugin>
</plugins>

Et

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

Sont équivalents selon la documentation Maven du plugin du compilateur puisque les éléments <source> et <target> de la configuration du compilateur utilisent les propriétés maven.compiler.source et maven.compiler.target s'ils sont définis.

Source

L'argument -source pour le compilateur Java.
La valeur par défaut est: 1.6.
La propriété utilisateur est: maven.compiler.source.

Cible

L'argument -target pour le compilateur Java.
La valeur par défaut est: 1.6.
La propriété utilisateur est: maven.compiler.target.

A propos des valeurs par défaut pour source et target, notez que depuis le 3.8.0 du compilateur maven, les valeurs par défaut sont passées de 1.5 à 1.6.

3) Le maven-compiler-plugin 3.6 et les versions ultérieures offrent une nouvelle façon :

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>3.8.0</version>
    <configuration>
        <release>9</release>
    </configuration>
</plugin>

Vous pouvez également déclarer simplement :

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

Mais pour le moment, cela ne fonctionnera pas comme maven-compiler-plugin par défaut la version que vous utilisez ne repose pas sur une version assez récente.

L'argument Maven release transmet release: une nouvelle option standard JVM que nous pourrions passer de Java 9 :

Compile sur l'API publique, prise en charge et documentée pour un version spécifique de la machine virtuelle.

Cette méthode fournit un moyen standard de spécifier la même version pour les options source, target et bootstrap JVM.
Notez que spécifier le bootstrap est une bonne pratique pour compilations croisées et cela ne fera pas de mal si vous ne faites pas de compilations croisées non plus.


Quelle est la meilleure façon de spécifier la version JDK?

La première méthode (<java.version>) n'est autorisée que si vous utilisez Spring Boot.

Pour Java 8 et ci-dessous :

Sur les deux autres façons : maven.compiler.source/maven.compiler.target propriétés ou en utilisant le maven-compiler-plugin, vous pouvez utiliser l'un ou l'autre. Cela ne change rien dans les faits puisque finalement les deux les solutions reposent sur les mêmes propriétés et le même mécanisme : le maven de base compilateur plugin.

Eh bien, si vous n'avez pas besoin de spécifier d'autres propriétés ou comportements que les versions Java dans le plugin du compilateur, utiliser cette méthode a plus de sens car elle est plus concise:

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

À Partir De Java 9 :

L'argument release (troisième point) est un moyen de considérer fortement si vous souhaitez utiliser la même version pour la source et la cible.

Quoi se produit si la version diffère entre le JDK dans JAVA_HOME et celle spécifiée dans le pom.xml?

Ce n'est pas un problème si le JDK référencé par le JAVA_HOME est compatible avec la version spécifiée dans le pom mais pour assurer une meilleure compatibilité entre compilations, pensez à ajouter l'option bootstrap JVM avec comme valeur le chemin du rt.jar de la version target.

Une chose importante à considérer est que la version source et la version target dans le Maven la configuration ne doit pas être supérieure à la version JDK référencée par le JAVA_HOME.
Une ancienne version du JDK ne peut pas compiler avec une version plus récente car elle ne connaît pas sa spécification.

Pour obtenir des informations sur les versions prises en charge par la source, la cible et la version selon le JDK utilisé, veuillez vous référer à compilation java : versions prises en charge par la source, la cible et la version.


Comment gérer le cas de JDK référencé par JAVA_HOME est non compatible avec les versions cible et/ou source java spécifiées dans le pom?

Par exemple, si votre JAVA_HOME fait référence à un JDK 1.7 et que vous spécifiez un JDK 1.8 comme source et cible dans la configuration du compilateur de votre pom.xml, ce sera un problème car comme expliqué, le JDK 1.7 ne sait pas comment compiler avec.
De son point de vue, il s'agit d'une version JDK inconnue puisqu'elle a été publiée après.
Dans ce cas, vous devez configurer le plugin Maven compiler pour spécifiez le JDK de cette façon:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <configuration>
        <source>1.8</source>
        <target>1.8</target>
        <compilerVersion>1.8</compilerVersion>      
        <fork>true</fork>
        <executable>D:\jdk1.8\bin\javac</executable>                
    </configuration>
</plugin>

Vous pourriez avoir plus de détails dans exemples avec le plugin maven compiler.


Il n'est pas demandé mais les cas où cela peut être plus compliqué sont lorsque vous spécifiez la source mais pas la cible. Il peut utiliser une version différente dans la cible en fonction de la version d'origine. Les règles sont particulières: vous pouvez les lire dans la partie Options de compilation croisée.


Pourquoi le plugin du compilateur est tracé dans la sortie à l'exécution de l'objectif Maven package même si vous ne le spécifiez pas dans le pom.xml?

Pour compiler votre code et plus généralement pour effectuer toutes les tâches requises pour un objectif maven, Maven a besoin d'outils. Donc, il utilise des plugins Maven de base (vous reconnaissez un plugin Maven de base par son groupId : org.apache.maven.plugins) pour effectuer les tâches requises: plugin de compilateur pour compiler des classes, plugin de test pour exécuter des tests, etc... Donc, même si vous ne déclarez pas ces plugins, ils sont liés au exécution du cycle de vie de Maven.
À la racine de votre projet Maven, vous pouvez exécuter la commande: mvn help:effective-pom pour utiliser efficacement le pom final. Vous pouvez voir entre autres informations, des plugins attachés par Maven (spécifiés ou non dans votre pom.xml), avec la version utilisée, leur configuration et les objectifs exécutés pour chaque phase du cycle de vie.

Dans la sortie de la mvn help:effective-pom commande, vous pouvez voir la déclaration de ces plugins dans le <build><plugins> élément, par exemple :

...
<plugin>
   <artifactId>maven-clean-plugin</artifactId>
   <version>2.5</version>
   <executions>
     <execution>
       <id>default-clean</id>
       <phase>clean</phase>
       <goals>
         <goal>clean</goal>
       </goals>
     </execution>
   </executions>
 </plugin>
 <plugin>
   <artifactId>maven-resources-plugin</artifactId>
   <version>2.6</version>
   <executions>
     <execution>
       <id>default-testResources</id>
       <phase>process-test-resources</phase>
       <goals>
         <goal>testResources</goal>
       </goals>
     </execution>
     <execution>
       <id>default-resources</id>
       <phase>process-resources</phase>
       <goals>
         <goal>resources</goal>
       </goals>
     </execution>
   </executions>
 </plugin>
 <plugin>
   <artifactId>maven-compiler-plugin</artifactId>
   <version>3.1</version>
   <executions>
     <execution>
       <id>default-compile</id>
       <phase>compile</phase>
       <goals>
         <goal>compile</goal>
       </goals>
     </execution>
     <execution>
       <id>default-testCompile</id>
       <phase>test-compile</phase>
       <goals>
         <goal>testCompile</goal>
       </goals>
     </execution>
   </executions>
 </plugin>
  ...

Vous pouvez avoir plus d'informations à ce sujet dans l'introduction du cycle de vie Maven dans la documentation Maven.

Néanmoins, vous pouvez déclarer ces plugins lorsque vous souhaitez les configurer avec d'autres valeurs comme valeurs par défaut (par exemple, vous l'avez fait lorsque vous avez déclaré le plugin maven-compiler dans votre pom.xml pour ajuster la version JDK à utiliser) ou lorsque vous souhaitez ajouter des exécutions de plugin non utilisées par défaut dans le cycle de vie Maven.

 153
Author: davidxxx, 2018-08-27 10:19:20

Considérez l'alternative:

<properties>
    <javac.src.version>1.8</javac.src.version>
    <javac.target.version>1.8</javac.target.version>
</properties>

Ce devrait être la même chose que maven.compiler.source/maven.compiler.target mais la solution ci-dessus fonctionne pour moi, sinon la seconde obtient la spécification parent (j'ai une matrioska de .pom)

 0
Author: Stefano, 2018-06-13 09:51:13