即使我只更改其中一个类,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 compile
, mvn package
and mvn install
.
当然,如果您有 10-15 个文件,这不是问题。但是,我有一千多个源文件,需要花费很多时间。
Maven 编译器插件是否有一些隐藏设置来仅重新编译修改过的文件?有什么解决方法吗?
Summary
当你can告诉 Maven“仅重新编译修改过的文件”,这样做会导致错误的结果。默认行为不是错误,而是有意的设计决策。
What useIncrementalCompilation
确实如此
温和地说,有关此主题的文档并不是最佳的。这是真正发生的事情(基于AbstractCompilerMojo 源代码 http://grepcode.com/file/repo1.maven.org/maven2/org.apache.maven.plugins/maven-compiler-plugin/3.3/org/apache/maven/plugin/compiler/AbstractCompilerMojo.java#686 from maven-compiler-plugin
3.3):
-
useIncrementalCompilation
set to false
(not recommended)
- 这只会编译比相应的类文件更新的源文件,即自上次编译过程以来已更改的源文件。正如 @Ivan 在另一个答案的评论中指出的那样,这不会重新编译使用更改后的类的其他类,可能会留下对不再存在的方法的引用,从而导致运行时错误。
-
useIncrementalCompilation
set to true
(default)
- To handle the problem outlined above, in this mode the compiler plugin will determine whether
- 当前模块依赖的任何 JAR 文件在当前构建运行中已更改,或者
- 自上次编译以来添加、删除或更改了任何源文件。
- 如果是这种情况,编译器插件会故意重新编译所有源代码,打印
Changes detected - recompiling the module!
所以总而言之,useIncrementalCompilation
应始终保留默认值true
.
为什么它不做其他事情
可以理解的是,有人可能会问:为什么插件不能确定哪些类受到更改的影响,而只重新编译这些类?在评论中MCOMPILER-205 https://issues.apache.org/jira/browse/MCOMPILER-205,Maven 开发者 Robert Scholte 给出了然后以下详细解释:
如果任何源文件已更改或删除,则所有文件都将被删除并重新编译。这样做的原因是,使用默认的 java 编译器简单地重新编译所有内容都非常快,可能比替代方案快得多,替代方案看起来类似于:
- 检测所有已更改的文件
- 分析所有源文件以映射类之间的所有关系
- 计算所有受影响的文件
- 重新编译受影响的文件
然而,正如罗伯特也,如果项目使用 Eclipse 编译器进行此分析,则可能不需要重新编译所有内容。但对于今天的 Maven 用户来说,这是一个有争议的问题,因为maven-compiler-plugin
尚未根据编译器的选择改变其行为。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)