Maven compiler recompile all files instead modified

两盒软妹~` 提交于 2019-12-17 17:41:41

问题


Even if I only change one of my classes, Maven always recompiles all of them. I use this plugin configuration:

<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>

This happens with mvn compile, mvn package and mvn install.

Of course this is not a problem if you have 10-15 files. However, I have more than one thousand source files and it takes a lot of time.

Does the Maven compiler plugin have some hidden settings to recompile only modified files? Are there any workarounds?


回答1:


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

Use it with Bulgarian notation (yes <-> no)

<useIncrementalCompilation>false</useIncrementalCompilation> means true and vice versa




回答2:


Summary

While you can tell Maven "to recompile only modified files", doing so will lead to wrong results. The default behavior is not a bug, but an intentional design decision.


What useIncrementalCompilation really does

The documentation on this topic is, to put it mildly, not optimal. Here is what really happens (based on AbstractCompilerMojo source from maven-compiler-plugin 3.3):

  • useIncrementalCompilation set to false (not recommended)
    • This will only compile source files which are newer than their corresponding class files, i.e. which have been changed since the last compilation process. As @Ivan notes in a comment on another answer, this will not recompile other classes which use the changed class, potentially leaving them with references to methods that no longer exist, leading to errors at runtime.
  • useIncrementalCompilation set to true (default)
    • To handle the problem outlined above, in this mode the compiler plugin will determine whether
      • any JAR files the current module depends on have been changed in the current build run, or
      • any source file was added, removed or changed since the last compilation.
    • If this is the case, the compiler plugin intentionally recompiles all sources, printing Changes detected - recompiling the module!

So in summary, useIncrementalCompilation should always be left at the default of true.


Why it does not do something else

Understandably, one might ask: why does the plugin not determine which classes are affected by the changes, and recompile only those classes? In the comments on MCOMPILER-205, Maven developer Robert Scholte gave a brief rationale and later confirmed the following detailed explanation:

If any source file has been changed or removed, all files are deleted and recompiled. The reason for this is that simply recompiling everything with the default java compiler is quite fast, likely much faster than the alternative, which would look similar to this:

  1. detect all changed files
  2. analyze all source files to map all relations between classes
  3. calculate all affected files
  4. recompile affected files

However, as Robert also writes, recompiling everything is probably not necessary if the project uses the Eclipse compiler, which does this analysis. But for today's Maven users, this is a moot point as maven-compiler-plugin does not yet change its behavior based on the choice of compiler.



来源:https://stackoverflow.com/questions/16963012/maven-compiler-recompile-all-files-instead-modified

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!