FIXED:这是maven-compiler-plugin 3.1中的known bug
我正在将1000多个java-sources项目的基于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
...
(仅针对某个软件包中的文件,这可能与其他代码未引用;不是我的来源,我只是想对构建进行整理)
编译不会失败,并且正在
生成具有更新时间戳的类/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] ------------------------------------------------------------------------
答案 0 :(得分:31)
这是maven-compiler-plugin 3.1中的一个已知问题。它在https://issues.apache.org/jira/browse/MCOMPILER-209中被跟踪(useIncrementalCompilation
标志已被破坏)。
该问题与另一个3.1错误https://issues.apache.org/jira/browse/MCOMPILER-205无关(其中不生成.class输出的文件始终标记为'陈旧')。
进一步测试后,回到3.0并没有真正解决问题(它只适用于下一个mvn clean compile
。但是,正如Michael Lemke在评论中建议的那样,将useIncrementalCompilation
标记为false
}是一个可行的替代品;现在,每次只重新编译有问题的包(而不是整个代码库)。
答案 1 :(得分:12)
Maven可能会显示如下消息:
[INFO]检测到更改 - 重新编译模块!
因为项目中有一个空的java文件(或所有注释掉的文件),它永远不会编译成类文件。
您可以通过使用-X运行maven来确定maven重建的原因。看看上面的消息。
答案 2 :(得分:6)
我的情况略有不同,所以我只是添加它,以防其他人有同样的问题。我的项目没有生成类,也没有package-info.java
;仅.java
中的src/main/java
个文件。
<强> TL;博士强>
更新至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>
再次进行增量构建之后我必须进行两次构建,因此需要进一步调查。这只是因为第一个编译生成了一个文件(称为inputFiles.lst
),用于确定已更改的文件,因此在下一次编译时,它可以使用该文件来检测更改。这由MCOMPILER-187上的a comment确认。
我意识到我正在使用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(而不是maven-compiler-plugin
3.0使用的1.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
是否存在,因为另一个插件可能导致它无法生成。
答案 3 :(得分:4)
我不明白为什么,但tucuxi答案的解决方案在我的案例中不起作用。在我的项目中,有数千个由特殊工具生成的文件,它的重新编译可能会浪费很多时间。
我尝试了以下插件配置(使用java级别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>
在第二次运行时,没有检测到过时的文件,但插件再次重新编译了所有项目。似乎默认情况下,增量编译实际上已禁用,即使指定了useIncrementalCompilation = true,仍然无法正常工作。
经过一些谷歌搜索,我只是简单地将useIncrementalCompilation参数值从“true”更改为“yes”,这对我来说很有用。
答案 4 :(得分:1)
如果您确定没有更改,则可以传入-Dmaven.main.skip
。我有一个在运行Proguard之后执行此操作的项目,因为这是重复使用Proguarded jar进行测试的唯一方法。 (注意:我在Proguard之前和之后都运行了相同的单元测试,以确保Proguard没有损坏任何东西。为了使它尽可能接近标准Maven工作流程,我在Surefire中进行了Proguard之前的运行, Proguard在故障保护中运行。)
答案 5 :(得分:0)
发生这种情况的另一种方法是,如果您的源文件位置和程序包名称不匹配。
例如如果您在src/main/java/com/example/MyClass.java
中有一个源文件,但是在不匹配的com.example.util
包中声明了该类:
package com.example.util;
class MyClass { ... }
编译后的类文件将以target/classes/com/example/util/MyClass.class
结尾,这会混淆“陈旧文件”检查。
答案 6 :(得分:0)
我将maven编译器插件回滚到2.3.2版本,并且它仅使用Java 8编译经过修改的类,而没有问题。
答案 7 :(得分:0)
遇到同样的问题。带有mvn compile
选项的Maven -X
表明问题是由package-info.java
文件引起的。
[DEBUG]检测到过时的源:... / 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。
答案 8 :(得分:0)
类名和文件名不匹配也会产生此错误。