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

时间:2013-06-06 13:10:49

标签: 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>

mvn compilemvn packagemvn install会发生这种情况。

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

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

2 个答案:

答案 0 :(得分:27)

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

将其与保加利亚表示法一起使用(是&lt; - &gt; no)

<useIncrementalCompilation>false</useIncrementalCompilation>表示正确,反之亦然

答案 1 :(得分:19)

摘要

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

useIncrementalCompilation真正做什么

温和地说,关于这个主题的文档不是最佳的。以下是真实情况(基于maven-compiler-plugin 3.3 AbstractCompilerMojo source

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

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

为什么它不做其他事

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

  

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

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

但是,正如Robert writes所述,如果项目使用Eclipse编译器进行此分析,则可能不需要重新编译所有内容。但对于今天的Maven用户来说,这是一个没有实际意义的点,因为maven-compiler-plugin尚未根据编译器的选择改变其行为。