Maven编译器重新编译所有文件而不是修改

2024-03-26

即使我只更改其中一个类,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 编译器简单地重新编译所有内容都非常快,可能比替代方案快得多,替代方案看起来类似于:

  1. 检测所有已更改的文件
  2. 分析所有源文件以映射类之间的所有关系
  3. 计算所有受影响的文件
  4. 重新编译受影响的文件

然而,正如罗伯特也,如果项目使用 Eclipse 编译器进行此分析,则可能不需要重新编译所有内容。但对于今天的 Maven 用户来说,这是一个有争议的问题,因为maven-compiler-plugin尚未根据编译器的选择改变其行为。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Maven编译器重新编译所有文件而不是修改 的相关文章

随机推荐