web-dev-qa-db-ja.com

Mavenコンパイラプラグインは、常にソースのセットを「失効」として検出します

修正済み:maven-compiler-plugin 3.1の 既知のバグ

1000以上のJavaソースプロジェクトのantベースのビルドをmavenに変換しています。これまでのところは良いですが、mvn compileを起動するたびに、(古いクラスを再利用する代わりに)すべてを再コンパイルします

mvn -X compileを使用すると、

[DEBUG] Stale source detected: /project_path/src/main/Java/package_path/AFile1.Java
[DEBUG] Stale source detected: /project_path/src/main/Java/package_path/AFile2.Java
...

特定のパッケージ内のファイルのみ、これはおそらく他のコードからは参照されません;私のソースではなく、ビルドをMaven化しようとしています)

コンパイルは失敗せず、更新されたタイムスタンプを持つクラスが生成されています

/project_path/target/classes/package_path/AFile1.class
/project_path/target/classes/package_path/AFile2.class
...

ただし、タイムスタンプを見ると、Javaファイルは昨日から変更されておらず、クラスファイルは最新です。これらのソースが古いと判断されるのはなぜですか?この問題をデバッグするにはどうすればよいですか?.

変更が発生していない場合でも1k +ファイルを再コンパイルする必要があるのはドラッグです...


サンプル出力:

$ mvn clean compile
[INFO] Scanning for projects...
[INFO]                                                                         
[INFO] ------------------------------------------------------------------------
[INFO] Building MyProject 1.9.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[WARNING] The POM for net.sourceforge:jffmpeg:jar:1.1.0 is missing, no dependency information available
[INFO] 
[INFO] --- maven-clean-plugin:2.4.1:clean (default-clean) @ my-project ---
[INFO] Deleting /project_path/target
[INFO] 
[INFO] --- maven-resources-plugin:2.5:resources (default-resources) @ my-project ---
[debug] execute contextualize
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] skip non existing resourceDirectory /project_path/src/main/resources
[INFO] 
[INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ my-project ---
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 1162 source files to project_path/target/classes
....
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 11.215s
[INFO] Finished at: Tue Jul 30 12:42:25 CEST 2013
[INFO] Final Memory: 25M/429M
[INFO] ------------------------------------------------------------------------



$ mvn compile
[INFO] Scanning for projects...
[INFO]                                                                         
[INFO] ------------------------------------------------------------------------
[INFO] Building MyProject 1.9.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[WARNING] The POM for net.sourceforge:jffmpeg:jar:1.1.0 is missing, no dependency information available
[INFO] 
[INFO] --- maven-resources-plugin:2.5:resources (default-resources) @ my-project ---
[debug] execute contextualize
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] skip non existing resourceDirectory /project_path/src/main/resources
[INFO] 
[INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ my-project ---
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 1162 source files to /project_path/target/classes
... 
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 12.140s
[INFO] Finished at: Tue Jul 30 12:42:44 CEST 2013
[INFO] Final Memory: 22M/379M
[INFO] ------------------------------------------------------------------------
46
tucuxi

これは、maven-compiler-plugin 3.1の既知の問題です。 https://issues.Apache.org/jira/browse/MCOMPILER-209useIncrementalCompilationフラグは壊れた)。

この問題は、別の3.1のバグとは無関係です。 https://issues.Apache.org/jira/browse/MCOMPILER-205 ( .classの出力には、常に「古い」というフラグが付けられます)。

さらにテストした後、3.0に戻っても問題は実際には修正されませんでした(次のmvn clean compile。ただし、Michael Lemkeがコメントで示唆しているように、useIncrementalCompilationfalseにマークすることは実行可能な代替です。現在では、コードベース全体ではなく、問題のパッケージのみが毎回再コンパイルされます。

31
tucuxi

Mavenは次のようなメッセージを表示する場合があります。

[情報]変更が検出されました-モジュールを再コンパイルします!

クラスファイルにコンパイルされないプロジェクトに空のJavaファイル(またはすべてコメント化された))があるためです。

-Xを指定してmavenを実行すると、mavenが再構築される理由を特定できます。上記のメッセージの近くを見てください。

15
jm.

私の状況はわずかに異なっていたので、誰かが同じ問題を抱えている場合に備えて、これを追加しています。私のプロジェクトには、生成されたクラスもpackage-info.Javaもありません。 .Java内のsrc/main/Javaファイルのみ。

tl; dr

maven-compiler-plugin 3.1に更新するか、maven-compiler-plugin 3.0を使用し、<overwrite>true</overwrite>maven-resources-pluginを設定しないでください。


ロングバージョン

Srcツリーの変更がゼロの場合、Mavenは常に次のような出力を表示していました。

$ mvn -o compile

[INFO] --- maven-compiler-plugin:3.0:compile (default-compile) @ my-project ---
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 134 source files to /home/me/my/project/target/classes

私のプロジェクトが使用している親POMのmaven-resources-pluginの構成だと思いました。

<plugin>
    <groupId>org.Apache.maven.plugins</groupId>
    <artifactId>maven-resources-plugin</artifactId>
    <configuration>
        <overwrite>true</overwrite>
    </configuration>
</plugin>

このプラグインを親POMから削除するか、<overwrite>false</overwrite>を使用してプロジェクトで再定義すると、増分ビルドの問題が修正されました。

Mavenが再度インクリメンタルビルドを行うように<overwrite>false</overwrite>を設定した後に2つのビルドを行う必要があるのではないかと考え、さらに調査しました。これは、最初のコンパイルで変更されたファイルの判別に使用されるファイル(inputFiles.lstと呼ばれる)が生成されるためです。したがって、次のコンパイルでは、そのファイルを使用して変更を検出できます。これは、MCOMPILER-187の コメント で確認されます。

maven-compiler-plugin 3.0を使用していて、アップグレードすることができることに気付きました

<plugin>
    <groupId>org.Apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>3.1</version>
</plugin>

また、問題を修正しました。 3.1は maven-shared-incremental 1.1を使用します(1.0ではなくmaven-compiler-plugin 3.0が使用します。 MCOMPILER-187 および MSHARED-264 に注意してください。 =変更をカバーする2つのバグです。

そのため、maven-compiler-plugin 3.0を使用して、target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst<overwrite>true</overwrite>を設定して生成されていないことに気付きました。そのため、これはである可能性がありますmaven-compiler-plugin 3.0を使用する場合、プロジェクトでインクリメンタルビルドが失敗する理由になります。

明らかに、コンパイルごとにリソースを上書きすることは通常は望ましくありませんが、ここでの主な問題はinputFiles.lstが生成されないため、Mavenがインクリメンタルビルドを作成できないことです。別のプラグインが何らかの原因でプラグインが生成されないため、inputFiles.lstの存在を確認してください。

7
andyb

理由はわかりませんが、tucuxiの答えの解決策は私の場合はうまくいきません。私のプロジェクトには、特別なツールによって生成された数千のファイルがあり、その再コンパイルは本当に多くの時間を浪費する可能性があります。

次のプラグイン構成を試しました(Java level 1.5):

<plugin>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>3.1</version>
    <configuration>
        <source>1.5</source>
        <target>1.5</target>
        <useIncrementalCompilation>true</useIncrementalCompilation>
    </configuration>
</plugin>

2回目の実行では、古いファイルは検出されませんでしたが、プラグインはすべてのプロジェクトを再コンパイルしました。増分コンパイルは実際にはデフォルトで無効にされており、useIncrementalCompilation = trueが指定されていても動作しないようです。

いくつかのグーグル検索の後、useIncrementalCompilationパラメーターの値を「true」から「yes」に変更しました。これでうまくいきます。

@ stackoverflow.com/a/19653164/184864

4

同じ問題に直面した。 Maven mvn compileオプションと-Xオプションは、問題がpackage-info.Javaファイルによって引き起こされることを示しました。

[デバッグ]古いソースが検出されました:.../package-info.Java

問題は、package-info.Javaに対して生成された。classファイルがないことです。

ソリューションはこのPRで見つかりました: https://github.com/Apache/flink/pull/5644/files 参照 MCOMPILER-205

<compilerArgs>
    <arg>-Xpkginfo:always</arg>
</compilerArgs>

つまり:

Package-info.Javaファイルごとに常にpackage-info.classを生成します。

1
Derp

変更がないことが確実な場合は、-Dmaven.main.skip。 Proguarded jarをテストに再利用する唯一の方法であるため、Proguardの実行後にこれを行うプロジェクトがあります。 (NB:Proguardが破損しないように、Proguardの前と同じ単体テストを実行します。これをできるだけ標準のMavenワークフローに近づけるために、SurefireでProguardを実行し、 ProguardはFailsafeで実行されます。)

1
Pr0methean

これが発生する別の方法は、ソースファイルの場所とパッケージ名が一致しない場合です。

例えばsrc/main/Java/com/example/MyClass.Javaにソースファイルがあるが、クラスが不一致のcom.example.utilパッケージで宣言されている場合:

package com.example.util;

class MyClass { ... }

コンパイルされたクラスファイルはtarget/classes/com/example/util/MyClass.classになり、これは「古いファイル」チェックを混乱させます。

0
Gary

Mavenコンパイラプラグインをバージョン2.3.2にロールバックし、修正されたクラスのみをJava 8で問題なくコンパイルします。

0
Ruslanas