web-dev-qa-db-ja.com

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>

そして、これをプラグイン管理タグにラップして、子pomがこれを使用できるようにします。最初の質問はプロパティとMavenコンパイラプラグインのJavaバージョンの設定の違いは何ですか?

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

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

これは、明示的に宣言していなくても、コンパイラプラグインがあることを示しています。でmvnパッケージの出力を実行する

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

私が宣言していない他のプラグインもあります。 つまり、これらのプラグインはデフォルトで、Maven pomの隠れた部分になっていますか?プロパティとmavenプラグイン構成要素でsource/targetを設定する際に違いはありますか?

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

125
Plebejusz

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

1)<Java.version>はMavenのドキュメントでは参照されていません。
これはSpring Bootの仕様です。
これにより、ソースとターゲットのJavaバージョンを同じバージョンに設定して、両方にJava 1.8を指定することができます。

<properties>
     <Java.version>1.8</Java.version>
</properties>   

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

2)sourcetargetを指定するための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>

コンパイラー構成内の<source>および<target>エレメントは、定義されている場合はプロパティーmaven.compiler.sourceおよびmaven.compiler.targetを使用するため、 コンパイラー・プラグインのMaven資料 によれば同等です。

source

Javaコンパイラの-source引数。
デフォルト値は1.6です。
ユーザープロパティはmaven.compiler.sourceです。

target

Javaコンパイラの-target引数。
デフォルト値は1.6です。
ユーザープロパティはmaven.compiler.targetです。

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

3)maven-compiler-plugin 3.6以降のバージョンは新しい方法を提供します。

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

以下のように宣言することもできます。

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

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

Mavenのrelease引数は、release:a { 新しいJVM標準オプション } _を伝達します。これは、Java 9から渡すことができます。

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

この方法により、sourcetarget、およびbootstrapのJVMオプションに同じバージョンを指定する標準的な方法が提供されます。
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のバージョンが異なるとどうなりますか?

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

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

使用されているJDKに従ってソース、ターゲット、およびリリースがサポートされているバージョンに関する情報を取得するには、 Javaコンパイル:ソース、ターゲットおよびリリースがサポートされているバージョン を参照してください。


Java_HOMEによって参照されるJDKの大文字と小文字の処理は、pomで指定されたJavaのターゲットバージョンやソースバージョンと互換性がありません。

たとえば、Java_HOMEがJDK 1.7を参照していて、pom.xmlのコンパイラ構成でソースおよびターゲットとして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コンパイラプラグインを使った例 でもっと詳細を知ることができます。


聞かれることはありませんが、sourceを指定してtargetを指定しない場合がより複雑になる可能性があります。ソースバージョンに応じてtargetに異なるバージョンを使用することがあります。ルールは特別です:あなたは Cross-Compilation Options part でそれらについて読むことができます。


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

コードをコンパイルし、さらに一般的にはMavenの目標に必要なすべてのタスクを実行するために、Mavenにはツールが必要です。そのため、コアMavenプラグイン(groupIdorg.Apache.maven.pluginsでコアMavenプラグインを認識します)を使用して必要なタスクを実行します。これらのプラグインを宣言してはいけません、それらはMavenライフサイクルの実行に縛られています。
あなたのMavenプロジェクトのルートディレクトリで、最後のpomを効果的に使うためにmvn help:effective-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のライフサイクルでデフォルトで使用されていないプラグインの実行を追加したい。

215
davidxxx

上記の解決策のどれもすぐに私のために働きませんでした。だから私は以下のことをしました: -

  1. 追加しました

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

    pom.xml内

  2. 「プロパティー」>「Javaビルド・パス」というプロジェクトに移動してから、JRE 1.5を指していたJREシステム・ライブラリーを削除しました。

  3. プロジェクトを強制的に更新しました。

0
Sen

代替案を検討してください。

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

これはmaven.compiler.source/maven.compiler.targetと同じものであるべきですが、上記の解決策は私にはうまくいきます。

0
Stefano