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

Tor*_*ten 17 maven maven-compiler-plugin

即使我只改变了我的一个课程,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>
Run Code Online (Sandbox Code Playgroud)

出现这种情况有mvn compile,mvn packagemvn install.

当然,如果您有10-15个文件,这不是问题.但是,我有超过一千个源文件,需要花费很多时间.

Maven编译器插件是否有一些隐藏设置来重新编译修改后的文件?有没有解决方法?

wap*_*gui 27

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

使用保加利亚表示法(是< - >否)

<useIncrementalCompilation>false</useIncrementalCompilation> 意味着真实,反之亦然

  • 所以这个设置可以被认为是"useSmartIncrementalCompilation",所以当我们将它设置为false时,我们只得到上面描述的基本(和危险).在maven 3中,"智能"似乎被打破了,而不是计算正确的依赖类,如果项目中的单个类被更改,它将所有类标记为依赖类,从而有效地使编译非增量. (6认同)
  • 请记住,使用此设置可以执行简单的渐进式编译,但它不是非常有用,因为它不会重新编译依赖类.因此,例如,如果你有一个类A调用类B的方法,并且你修改了B中方法的签名,maven将只重新编译B并且编译将成功,但现在A有一个对B中不存在的方法的引用. (5认同)
  • 亲爱的wapgui,你的回答是误导性的,请看@Ivan上面的评论.请在答案中添加警告. (2认同)
  • @robert 恐怕我不同意。问题中没有任何内容表明“寻求默认的 javac 行为......”或“风险被理解并接受为公平的权衡”。答案中也没有注明,因此我建议在答案中添加警告。 (2认同)

Jen*_*ann 22

摘要

虽然您可以告诉Maven"仅重新编译已修改的文件",但这样做会导致错误的结果.默认行为不是错误,而是故意的设计决策.


useIncrementalCompilation真的是什么

有点说,这个主题的文档并不是最佳的.这是真的发生(基于什么AbstractCompilerMojo源maven-compiler-plugin3.3):

  • useIncrementalCompilation设置为false(不推荐)
    • 这将仅编译比其对应的类文件更新的源文件,即自上次编译过程以来已更改的源文件.正如@Ivan在对另一个答案的评论中指出的那样,这不会重新编译使用已更改类的其他类,可能会让它们引用不再存在的方法,从而导致运行时出错.
  • useIncrementalCompilation设为true(默认)
    • 为了解决上面概述的问题,在这种模式下,编译器插件将确定是否
      • 当前模块所依赖的任何JAR文件在当前构建运行中已更改,或者
      • 自上次编译以来添加,删除或更改了任何源文件.
    • 如果是这种情况,编译器插件会故意重新编译所有源,打印 Changes detected - recompiling the module!

总而言之,useIncrementalCompilation应始终保留默认值true.


为什么它不做其他事情

可以理解的是,有人可能会问:为什么插件不能确定哪些类受更改影响,只重新编译那些类?在对MCOMPILER-205的评论中,Maven开发人员Robert Scholte给出了简要的理由,后来确认了以下详细说明:

如果更改或删除了任何源文件,则会删除并重新编译所有文件.这样做的原因是简单地使用默认的java编译器重新编译所有内容非常快,可能比替代方法快得多,这看起来类似于:

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

但是,正如Robert 所写的那样,如果项目使用Eclipse编译器进行此分析,则可能不需要重新编译所有内容.但对于今天的Maven用户来说,这是一个有争议的问题,因为maven-compiler-plugin它还没有根据编译器的选择改变其行为.

  • 我认为您误解了开发人员的评论。我一开始只是挠头,但我认为他的意思是javac提供的* default *增量编译速度很快。我非常怀疑他的意思是,每次进行更改时,最好重新编译*所有*。您只需要一个&gt; 100个源文件的项目即可显示出这些废话。 (2认同)