web-dev-qa-db-ja.com

Mavenコンパイラは、変更された代わりにすべてのファイルを再コンパイルします

クラスの1つだけを変更した場合でも、Mavenは常にすべてのクラスを再コンパイルします。私はこのプラグイン構成を使用します:

<plugins>
    <plugin>
      <groupId>org.Apache.maven.plugins</groupId>
      <artifactId>maven-compiler-plugin</artifactId>
      <version>3.1</version>
      <configuration>
        <staleMillis>1</slateMillis>
        <useIncrementalCompilation>true</useIncrementalCompilation>
      </configuration>
    </plugin>
</plugins>

これは、mvn compilemvn package、およびmvn installで発生します。

もちろん、10〜15個のファイルがある場合、これは問題ではありません。しかし、私は1000を超えるソースファイルを持っており、時間がかかります。

Mavenコンパイラプラグインには、変更されたファイルのみを再コンパイルするための非表示の設定がいくつかありますか?回避策はありますか?

19
Torsten

https://issues.Apache.org/jira/browse/MCOMPILER-209

ブルガリア語の表記で使用します(はい<->いいえ)

<useIncrementalCompilation>false</useIncrementalCompilation>は真を意味し、その逆も同様です。

27
wapgui

概要

canはMavenに「変更されたファイルのみを再コンパイルする」ように指示できますが、そうすると間違った結果になります。デフォルトの動作はバグではなく、意図的な設計上の決定です。


useIncrementalCompilationが実際に行うこと

このトピックに関するドキュメントは、控えめに言っても、最適ではありません。これが実際に起こることです( AbstractCompilerMojo source from maven-compiler-plugin 3.3に基づく):

  • useIncrementalCompilationfalseに設定(非推奨
    • これは、対応するクラスファイルよりも新しい、つまり最後のコンパイルプロセス以降に変更されたソースファイルのみをコンパイルします。 @Ivanが別の回答のコメントで指摘しているように、これは変更されたクラスを使用する他のクラスを再コンパイルせず、存在しないメソッドへの参照を残す可能性があり、実行時にエラーが発生します。
  • useIncrementalCompilationtrueに設定(default
    • 上記の問題を処理するために、このモードでは、コンパイラプラグインがかどうかを判断します。
      • 現在のモジュールが依存するJARファイルは、現在のビルド実行で変更されているか、または
      • 前回のコンパイル以降に追加、削除、または変更されたソースファイル。
    • この場合、コンパイラプラグインは意図的にすべてのソースを再コンパイルし、Changes detected - recompiling the module!を出力します。

したがって、要約すると、useIncrementalCompilationは常にデフォルトのtrueのままにしておく必要があります。


なぜそれが他のことをしないのか

当然のことながら、プラグインが変更の影響を受けるクラスを判別せず、それらのクラスのみを再コンパイルするのはなぜですか? MCOMPILER-205 に関するコメントで、Maven開発者のRobert Scholteは 簡単な理論的根拠 以降 確認済み 次の詳細な説明をしました。

ソースファイルが変更または削除された場合、すべてのファイルが削除され、再コンパイルされます。この理由は、デフォルトのJavaコンパイラですべてを再コンパイルするだけで非常に高速であり、おそらく次のように見える代替よりもはるかに高速であるためです。

  1. 変更されたすべてのファイルを検出する
  2. すべてのソースファイルを分析して、クラス間のすべての関係をマッピングします
  3. 影響を受けるすべてのファイルを計算する
  4. 影響を受けるファイルを再コンパイルする

ただし、Robertも writes であるため、プロジェクトでこの分析を行うEclipseコンパイラを使用している場合は、すべてを再コンパイルする必要はおそらくありません。しかし、今日のMavenユーザーにとって、これは重要なポイントです。maven-compiler-pluginは、コンパイラーの選択に基づいてその動作をまだ変更していないからです。

21
Jens Bannmann