1. ホーム

[解決済み】mavenでJavaのバージョンを指定する - プロパティとコンパイラープラグインの相違点

2022-04-19 05:37:07

質問

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

そして、これをプラグイン管理タグでラップして、子ポムで使用できるようにします。そこで最初の質問がこれです。

プロパティでJavaのバージョンを設定するのと、Mavenコンパイラ・プラグインで設定するのとでは、どのような違いがありますか?

明確な回答は見つかりませんでしたが、調べる過程でこのような方法でも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 ?

解決方法は?

JDKのバージョンを指定するには?

3つの方法のいずれかを使用します。(1) Spring Bootの機能、または(2)のいずれかでMavenのコンパイラープラグインを使用する。 source &を使用します。 target または(3)で release .

スプリングブート

  1. <java.version> は、Maven のドキュメントでは参照されていません。

    Spring Boot特有のものです。

    このように、ソースとターゲットのjavaのバージョンを同じにすることで、両方にjava 1.8を指定することができるのです。

    1.8

Spring Bootを使用している方はご自由にお使いください。

maven-compiler-pluginsource & target

  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.sourcemaven.compiler.target が定義されている場合。

ソース

<ブロッククオート

-source Java コンパイラの引数を指定します。

デフォルト値は 1.6 .

ユーザープロパティは maven.compiler.source .

対象

<ブロッククオート

-target Java コンパイラの引数を指定します。

デフォルト値は 1.6 .

ユーザープロパティは maven.compiler.target .

のデフォルト値について sourcetarget は、次のことに注意してください。 であるため 3.8.0 から、maven コンパイラのデフォルト値に変更されました。 1.5 から 1.6 .

maven-compiler-pluginrelease の代わりに source & target

  1. maven-compiler-pluginは 3.6 およびそれ以降のバージョンでは、新しい方法を提供しています。

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

また、.NETだけを宣言することもできます。

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

しかし、このままでは maven-compiler-plugin デフォルトで使用しているバージョンは、十分に新しいバージョンに依存していません。

Mavenの release 引数は release : a 新JVM標準オプション Java 9から受け継がれたものです。

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

この方法によって、同じバージョンを source というように targetbootstrap JVMのオプションです。

を指定することに注意してください。 bootstrap は、クロスコンパイルを行う際のグッドプラクティスであり、クロスコンパイルを行わない場合でも支障はないでしょう。


JDKのバージョンを指定する方法はどれが良いですか?

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

Java 8 以下の場合 :

他の2つの方法について maven.compiler.source / maven.compiler.target プロパティ または を使用しています。 maven-compiler-plugin のように、どちらか一方を使用することができます。最終的に2つのソリューションは、同じプロパティと同じメカニズム(maven core compiler plugin)に依存しているので、事実上、何も変わりません。

まあ、コンパイラ・プラグインで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は、そのJDKに対応するものであれば問題ありません。 JAVA_HOME は pom で指定されたバージョンと互換性がありますが、より良いクロスコンパイルの互換性を確保するために bootstrap のパスを値として持つJVMオプションです。 rt.jartarget のバージョンになります。

重要なことは sourcetarget で参照されるJDKのバージョンより優れていてはいけません。 JAVA_HOME .

古いバージョンのJDKは、その仕様を知らないので、最近のバージョンとコンパイルすることができません。

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


JAVA_HOMEで参照されるJDKが、pomで指定されたjavaターゲットやソースのバージョンと互換性がない場合、どのように対処すればよいですか?

例えば JAVA_HOME がJDK 1.7を参照しているのに、pom.xmlのコンパイラ設定でsourceとtargetにJDK 1.8を指定すると、説明したように、JDK 1.7はどのようにコンパイルすればよいかわからないため問題になる。

その点からすると、その後にリリースされたので、未知のJDKバージョンということになります。

この場合、このようにJDKを指定するようにMavenのコンパイラープラグインを設定する必要があります :

<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コンパイラープラグインを使用した例 .


質問されていませんが、より複雑になるケースは、ソースを指定し、ターゲットを指定しない場合です。ソースのバージョンによってターゲットで使用するバージョンが異なる可能性があります。ルールは特殊です。 クロスコンパイルオプションの部分 .


Maven 実行時の出力でコンパイラプラグインがトレースされる理由 package pom.xmlで指定していなくてもゴールに到達するのですか?

コードをコンパイルし、より一般的にはMavenの目標に必要なすべてのタスクを実行するために、Mavenはツールを必要とします。そのため、コア Maven プラグインを使用します (コア Maven プラグインは、その groupId : org.apache.maven.plugins クラスをコンパイルするためのcompilerプラグイン、テストを実行するためのtestプラグイン、などなど...)が必要なタスクを実行します。つまり、これらのプラグインは宣言しなくても、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ライフサイクルでデフォルトでは使用しないいくつかのプラグイン実行を追加したいときに、これらのプラグインを宣言することができます。