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?
detect all changed files. analyze all source files to map all relations between classes. calculate all affected files. recompile affected files.
The Compiler Plugin is used to compile the sources of your project. Since 3.0, the default compiler is javax. tools. JavaCompiler (if you are using java 1.6) and is used to compile Java sources.
Show activity on this post. Create a pom-only ( <packaging>pom</packaging> ) project that has the compiler settings (and any other default settings) you want. You give treat it like any other project (release it; deploy it to your Maven repo, etc.). It doesn't help much if all you want to set is compiler settings.
mvn test-compile: Compiles the test source code. mvn test: Runs tests for the project. mvn package: Creates JAR or WAR file for the project to convert it into a distributable format. mvn install: Deploys the packaged JAR/ WAR file to the local repository.
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.
useIncrementalCompilation
really doesThe 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) useIncrementalCompilation
set to true
(default) Changes detected - recompiling the module!
So in summary, useIncrementalCompilation
should always be left at the default of true
.
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:
- detect all changed files
- analyze all source files to map all relations between classes
- calculate all affected files
- 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://issues.apache.org/jira/browse/MCOMPILER-209
Use it with Bulgarian notation (yes <-> no)
<useIncrementalCompilation>false</useIncrementalCompilation>
means true and vice versa
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With