Specifica della versione java in maven-differenze tra proprietà e plugin del compilatore


Non ho molta esperienza con maven e mentre sperimentavo con il progetto multi-modulo ho iniziato a chiedermi come posso specificare la versione java per tutti i miei moduli figlio nel genitore maven pom. Fino ad oggi stavo usando solo:

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

Ma durante la ricerca ho scoperto che puoi anche specificare la versione java nel plugin del compilatore maven, in questo modo:

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

E quindi avvolgerlo nel tag di gestione plugin per abilitare l'utilizzo di questo pon figlio. Quindi la prima domanda è quali sono i differenze beetwen impostazione della versione java nelle proprietà e nel plugin del compilatore maven?

Non sono riuscito a trovare una risposta chiara, ma nel processo di ricerca ho scoperto che è anche possibile specificare la versione java in questo modo:

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

Che suggeriscono che il plugin del compilatore è lì anche se non lo dichiaro esplicitamente. Esecuzione di uscite pacchetto mvn con

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

E alcuni altri plugin che non ho dichiarato. Quindi quei plugin sono predefiniti, parte nascosta di maven pom? Ce ne sono differenze beetwen impostazione sorgente / destinazione nelle proprietà e nell'elemento di configurazione del plugin maven?

Alcune altre domande sono - in che modo dovrebbe essere usato (e quando se non sono uguali)? Quale è il migliore per il progetto multi-modulo e cosa succede se la versione java specificata in pom è diversa dalla versione indicata in JAVA_HOME?

Author: Gray, 2016-08-10

2 answers

Come specificare la versione JDK?

1) <java.version> non viene fatto riferimento nella documentazione Maven.
È una specificità di avvio a molla.
Consente di impostare la versione java di origine e quella di destinazione con la stessa versione come questa per specificare java 1.8 per entrambi:

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

Sentitevi liberi di usarlo se si utilizza Spring Boot.

2) Utilizzando maven-compiler-plugin o maven.compiler.source/maven.compiler.target le proprietà per specificare source e target sono equivalenti.

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

E

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

Sono equivalenti secondo la documentazione di Maven del plugin del compilatore poiché gli elementi <source> e <target> nella configurazione del compilatore utilizzano le proprietà maven.compiler.source e maven.compiler.target se sono definiti.

Fonte

L'argomento -source per il compilatore Java.
Il valore predefinito è: 1.6.
La proprietà utente è: maven.compiler.source.

Obiettivo

L'argomento -target per il compilatore Java.
Il valore predefinito è: 1.6.
La proprietà utente è: maven.compiler.target.

Circa i valori predefiniti per source e target, si noti che dal 3.8.0 del compilatore maven, i valori predefiniti sono cambiati da 1.5 a 1.6.

3) Il plugin maven-compiler 3.6 e le versioni successive forniscono un nuovo modo:

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

Potresti anche dichiarare solo:

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

Ma al momento non funzionerà come predefinito maven-compiler-plugin la versione che usi non si basa su una versione abbastanza recente.

L'argomento Maven release trasmette release: una nuova opzione standard JVM che potremmo passare da Java 9:

Compila l'API pubblica, supportata e documentata per un versione VM specifica.

In questo modo fornisce un modo standard per specificare la stessa versione per le opzioni source, target e bootstrap JVM.
Si noti che specificare bootstrap è una buona pratica per cross compilations e non farà male se non si fanno cross compilations sia.


Qual è il modo migliore per specificare la versione JDK?

Il primo modo (<java.version>) è consentito solo se si utilizza Spring Boot.

Per Java 8 e seguenti :

Circa gli altri due modi: valutare il maven.compiler.source/maven.compiler.target proprietà o utilizzando il maven-compiler-plugin, è possibile utilizzare uno o l'altro. Non cambia nulla nei fatti dal momento che finalmente i due le soluzioni si basano sulle stesse proprietà e sullo stesso meccanismo : il plugin maven core compiler.

Bene, se non è necessario specificare altre proprietà o comportamenti rispetto alle versioni Java nel plugin del compilatore, usare questo modo ha più senso in quanto è più conciso:

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

Da Java 9 :

L'argomento release (terzo punto) è un modo per considerare fortemente se si desidera utilizzare la stessa versione per l'origine e la destinazione.

Cosa succede se la versione differisce tra il JDK in JAVA_HOME e quale specificato nel pom.xml?

Non è un problema se il JDK a cui fa riferimento JAVA_HOME è compatibile con la versione specificata nel pom, ma per garantire una migliore compatibilità cross-compilation pensa di aggiungere l'opzione bootstrap JVM con come valore il percorso della rt.jar della versione target.

Una cosa importante da considerare è che la versione {[12] } e target nel Maven la configurazione non deve essere superiore alla versione JDK a cui fa riferimento JAVA_HOME.
Una versione precedente di JDK non può essere compilata con una versione più recente poiché non conosce le sue specifiche.

Per ottenere informazioni sulle versioni supportate di origine, destinazione e rilascio in base al JDK utilizzato, fare riferimento a compilazione java : versioni supportate di origine, destinazione e rilascio.


Come gestire il caso di JDK a cui fa riferimento JAVA_HOME è non compatibile con le versioni java target e / o source specificate nel pom?

Ad esempio, se il tuo JAVA_HOME si riferisce a un JDK 1.7 e specifichi un JDK 1.8 come origine e destinazione nella configurazione del compilatore del tuo pom.xml, sarà un problema perché come spiegato, il JDK 1.7 non sa come compilare.
Dal suo punto di vista, è una versione JDK sconosciuta da quando è stata rilasciata dopo di essa.
In questo caso, è necessario configurare il plugin del compilatore Maven per specificare il JDK in questo modo :

<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>

Potresti avere maggiori dettagli negli esempi con il plugin del compilatore maven.


Non viene chiesto, ma i casi in cui ciò potrebbe essere più complicato è quando si specifica origine ma non destinazione. Può utilizzare una versione diversa in target in base alla versione di origine. Le regole sono particolari : puoi leggerle in la parte Opzioni di compilazione incrociata.


Perché il plugin del compilatore è tracciato in l'output all'esecuzione dell'obiettivo Maven package anche se non lo si specifica nel pom.xml?

Per compilare il codice e più in generale per eseguire tutte le attività richieste per un obiettivo Maven, Maven ha bisogno di strumenti. Quindi, usa i plug - in core Maven (riconosci un plug-in core Maven dal suo groupId : org.apache.maven.plugins) per eseguire le attività richieste: plug-in del compilatore per la compilazione di classi, plug-in di test per l'esecuzione di test e così via... Quindi, anche se non dichiari questi plugin, sono legati al esecuzione del ciclo di vita di Maven.
Nella directory principale del tuo progetto Maven, puoi eseguire il comando: mvn help:effective-pom per utilizzare efficacemente il pom finale. Potresti vedere tra le altre informazioni, i plugin allegati da Maven (specificati o meno nel tuo pom.xml), con la versione utilizzata, la loro configurazione e gli obiettivi eseguiti per ogni fase del ciclo di vita.

Nell'output del comando mvn help:effective-pom, è possibile vedere la dichiarazione di questi plugin principali nell'elemento <build><plugins>, ad esempio :

...
<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>
  ...

Puoi avere maggiori informazioni su di esso in l'introduzione del ciclo di vita di Maven nella documentazione di Maven.

Tuttavia, puoi dichiarare questi plugin quando vuoi configurarli con altri valori come valori predefiniti (ad esempio, lo hai fatto quando hai dichiarato il plugin maven-compiler nel tuo pom.xml per regolare la versione JDK da utilizzare) o quando si desidera aggiungere alcune esecuzioni di plugin non utilizzate di default nel ciclo di vita di Maven.

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

Considera l'alternativa:

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

Dovrebbe essere la stessa cosa di maven.compiler.source/maven.compiler.target ma la soluzione sopra funziona per me, altrimenti la seconda ottiene la specifica genitore (ho una matrioska di .pom)

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