Maven で Java バージョンを指定する - プロパティとコンパイラ プラグインの違い 質問する

Maven で Java バージョンを指定する - プロパティとコンパイラ プラグインの違い 質問する

私は Maven の経験があまりなく、マルチモジュール プロジェクトを試しているときに、親 Maven pom 内のすべての子モジュールの Java バージョンを指定するにはどうすればよいか疑問に思い始めました。今日まで、私は次のように使用していました。

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

...しかし、調べてみると、次のように Maven コンパイラ プラグインで Java バージョンを指定できることがわかりました。

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

そして、これをプラグイン管理タグにラップして、子 poms での使用を有効にします。最初の質問は次のとおりです。

プロパティと Maven コンパイラ プラグインで Java バージョンを設定する場合の違いは何ですか?

明確な答えは見つかりませんでしたが、調査の過程で、次のように Java バージョンを指定することもできることがわかりました。

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

mvn package...これは、明示的に宣言していなくてもコンパイラプラグインが存在することを示唆しています。

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

...そして私が宣言しなかった他のいくつかのプラグイン。

では、これらのプラグインはデフォルトで、Maven pom の非表示の部分ですか? プロパティと Maven プラグイン構成要素でのソース/ターゲットの設定に違いはありますか?

その他の質問としては、どちらの方法を使用するべきか(そして、それらが等しくない場合はいつ使用するか)?マルチモジュール プロジェクトにはどちらが最適か、また、pom で指定された Java バージョンが で指定されたバージョンと異なる場合はどうなりますかJAVA_HOME

ベストアンサー1

JDK バージョンを指定するにはどうすればいいですか?

source3 つの方法のいずれかを使用します: (1) Spring Boot 機能、または (2)とtarget(3) のいずれかを使用した Maven コンパイラ プラグインを使用しますrelease

スプリングブート

  1. <java.version>Maven ドキュメントでは参照されていません。
    これは Spring Boot 特有のものです。
    これにより、ソースとターゲットの Java バージョンを同じバージョンに設定できます。たとえば、次のように両方に Java 1.8 を指定します。

    1.8

Spring Boot をお使いの場合はお気軽にご利用ください。

maven-compiler-pluginsourcetarget

  1. maven-compiler-pluginまたはmaven.compiler.source/プロパティを使用することmaven.compiler.targetは同等です。

それは確かにそうです:

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

は以下と同等です:

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

によるコンパイラプラグインのMavenドキュメントコンパイラ構成内のおよび<source>要素は、定義されている場合は<target>プロパティ および を使用するmaven.compiler.sourceためです。maven.compiler.target

ソース

-sourceJava コンパイラの引数。注
: 3.8.0 以降、デフォルト値は 1.5 から 1.6 に変更されました。3.9.0 以降、デフォルト値は 1.6 から 1.7 に変更されました。
デフォルト値は 1.7 です。
ユーザー プロパティは ですmaven.compiler.source

目標

-targetJava コンパイラの引数。注
: 3.8.0 以降、デフォルト値は 1.5 から 1.6 に変更されました。3.9.0 以降、デフォルト値は 1.6 から 1.7 に変更されました。
デフォルト値は: です1.6
ユーザー プロパティは: ですmaven.compiler.target

sourceおよびのデフォルト値についてはtarget、次の点に注意してください。Mavenコンパイラの以降3.8.0、デフォルト値は から に変更されました1.51.6

maven-compiler-plugin&releaseの代わりにsourcetarget

  1. maven-compiler-plugin3.6以降のバージョンでは、新しい方法が提供されています:

    org.apache.maven.plugins maven-compiler-plugin 3.8.0 9

次のように宣言することもできます:

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

ただし、現時点では、maven-compiler-plugin使用するデフォルト バージョンが十分に新しいバージョンに依存していないため、機能しません。

Mavenのrelease議論はrelease次のことを伝えている。新しい JVM 標準オプションJava 9から渡すことができるもの:

特定の VM バージョン用の、公開され、サポートされ、文書化された API に対してコンパイルします。

sourceこの方法は、、、およびtargetJVMオプションに同じバージョンを指定する標準的な方法を提供しますbootstrap
を指定することはbootstrapクロス コンパイルでは良い習慣であり、クロス コンパイルを行わない場合でも問題はありません。


JDK バージョンを指定する最適な方法は何ですか?

最初の方法 ( <java.version>) は、Spring Boot を使用する場合にのみ許可されます。

Java 8 以下の場合:

他の 2 つの方法 ( maven.compiler.source/maven.compiler.targetプロパティを評価する方法を使用する方法)についてmaven-compiler-pluginは、どちらか一方を使用できます。 最終的には 2 つのソリューションが同じプロパティと同じメカニズム (Maven コア コンパイラ プラグイン) に依存しているため、事実に変化はありません。

コンパイラ プラグインで Java バージョン以外のプロパティや動作を指定する必要がない場合は、この方法の方が簡潔なので理にかなっています。

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

Java 9から:

引数release(3 番目のポイント)は、ソースとターゲットに同じバージョンを使用するかどうかを強く検討する方法です。

JAVA_HOME の JDK のバージョンと pom.xml で指定された JDK のバージョンが異なる場合はどうなりますか?

によって参照される JDK が pom で指定されたバージョンと互換性がある場合は問題はありませんJAVA_HOMEが、クロスコンパイルの互換性を高めるには、バージョンのbootstrapのパスを値として指定した JVM オプションを追加することを検討してください。rt.jartarget

考慮すべき重要な点は、Maven 構成のsourceおよび のバージョンが、 によって参照される JDK バージョンよりも上位であってはならないということです。JDKの古いバージョンは、その仕様を認識していないため、新しいバージョンでコンパイルできません。targetJAVA_HOME

使用されているJDKに応じてサポートされているソース、ターゲット、リリースのバージョンに関する情報を取得するには、以下を参照してください。Java コンパイル: ソース、ターゲット、リリースでサポートされているバージョン


JAVA_HOME によって参照される JDK が、POM で指定された Java ターゲットおよび/またはソース バージョンと互換性がない場合は、どのように処理しますか?

たとえば、JAVA_HOMEJDK 1.7 を参照しているのに、pom.xml のコンパイラ構成でソースとターゲットとして JDK 1.8 を指定した場合、前述のように JDK 1.7 はコンパイル方法を知らないため、問題が発生します。JDK 1.7 の
観点から見ると、JDK 1.7 はそれ以降にリリースされたため、不明な JDK バージョンです。
この場合、Maven コンパイラ プラグインを構成して、次のように JDK を指定する必要があります。

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

詳細はMavenコンパイラプラグインの例


尋ねられることはありませんが、ソースを指定してターゲットを指定しない場合は、より複雑になる可能性があります。ソースのバージョンに応じて、ターゲットで異なるバージョンが使用される可能性があります。ルールは特殊です。それらについては、以下で読むことができます。クロスコンパイルオプション部分


packagepom.xml で指定していなくても、Maven ゴールの実行時にコンパイラ プラグインが出力にトレースされるのはなぜですか?

コードをコンパイルし、より一般的には Maven の目標に必要なすべてのタスクを実行するには、Maven にツールが必要です。そのため、コア Maven プラグイン (: でコア Maven プラグインを識別しますgroupId)を使用しorg.apache.maven.pluginsて、クラスをコンパイルするためのコンパイラ プラグイン、テストを実行するためのテスト プラグインなど、必要なタスクを実行します。したがって、これらのプラグインを宣言しない場合でも、Maven ライフサイクルの実行にバインドされます。Maven
プロジェクトのルート ディレクトリで、: コマンドを実行して、mvn help:effective-pom最終的な pom を効果的に使用できます。他の情報とともに、Maven によって添付されたプラグイン (pom.xml で指定されているかどうかに関係なく)、使用されているバージョン、その構成、ライフサイクルの各フェーズで実行された目標を確認できます。

コマンドの出力ではmvn help:effective-pom、要素内のこれらのコア プラグインの宣言を確認できます<build><plugins>。次に例を示します。

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

詳細は以下をご覧ください。Maven ドキュメントにおける Maven ライフサイクルの紹介

ただし、他の値をデフォルト値として設定する場合 (たとえば、使用する JDK バージョンを調整するために pom.xml で maven-compiler プラグインを宣言した場合)、または Maven ライフサイクルでデフォルトでは使用されないプラグイン実行を追加する場合は、これらのプラグインを宣言できます。

おすすめ記事