Dan Berindei created MCOMPILER-433:
--------------------------------------

             Summary: mvn clean compile test compiles the source files twice
                 Key: MCOMPILER-433
                 URL: https://issues.apache.org/jira/browse/MCOMPILER-433
             Project: Maven Compiler Plugin
          Issue Type: Bug
    Affects Versions: 3.8.1
            Reporter: Dan Berindei


When one invokes {{mvn clean compile test}}, the {{default-compile}} execution 
runs twice.
 This is because 
{{org.apache.maven.lifecycle.internal.DefaultLifecycleExecutionPlanCalculator#calculateMojoExecutions()}}
 (which hasn't changed in 6 years) collects the list of mojo executions in a 
list, and for each phase on the command-line it adds the mojo executions for 
that phase and its dependencies, even if some executions already exist in the 
list. E.g.
{noformat}
mojoExecutions = {java.util.ArrayList}  size = 8
 0 = {org.apache.maven.plugin.MojoExecution} 
"org.apache.maven.plugins:maven-clean-plugin:2.5:clean {execution: 
default-clean}"
 1 = {org.apache.maven.plugin.MojoExecution} 
"org.apache.maven.plugins:maven-resources-plugin:2.6:resources {execution: 
default-resources}"
 2 = {org.apache.maven.plugin.MojoExecution} 
"org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile {execution: 
default-compile}"
 3 = {org.apache.maven.plugin.MojoExecution} 
"org.apache.maven.plugins:maven-resources-plugin:2.6:resources {execution: 
default-resources}"
 4 = {org.apache.maven.plugin.MojoExecution} 
"org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile {execution: 
default-compile}"
 5 = {org.apache.maven.plugin.MojoExecution} 
"org.apache.maven.plugins:maven-resources-plugin:2.6:testResources {execution: 
default-testResources}"
 6 = {org.apache.maven.plugin.MojoExecution} 
"org.apache.maven.plugins:maven-compiler-plugin:3.8.1:testCompile {execution: 
default-testCompile}"
 7 = {org.apache.maven.plugin.MojoExecution} 
"org.apache.maven.plugins:maven-surefire-plugin:2.12.4:test {execution: 
default-test}"
{noformat}
 

The second execution of {{maven-compiler-plugin}} version 3.8.0 used to check 
that the sources haven't changed and do nothing. But that check was wrong, 
because it didn't check any class files, and MCOMPILER-349 replaced it with 
another check that is also wrong, because it 
({{org.apache.maven.plugin.compiler.AbstractCompilerMojo#isDependencyChanged()}})
 checks for changes since the start of the build in all the classes on the 
module's classpath, including {{target/classes}}.
 This means the second execution of {{maven-compiler-plugin}} verison 3.8.1 
deletes all the {{.class}} files from {{target/classes}}. It does not delete 
the files generated by annotation processors in 
{{target/generated-sources/annotations}}, but it also doesn't add them to the 
Javac sources parameter because 
{{org.apache.maven.plugin.compiler.AbstractCompilerMojo#getCompileSources()}} 
ignores the generated sources directory:
{noformat}
compileSourceRoots = {java.util.ArrayList}  size = 3
 0 = "/home/dan/Work/maven-compiler-test/src/main/java"
 1 = "/home/dan/Work/maven-compiler-test/target/generated-sources/annotations"
 2 = "/home/dan/Work/maven-compiler-test/target/generated-sources/annotations"
{noformat}
{noformat}
sources = {java.util.HashSet}  size = 2
 0 = {java.io.File} 
"/home/dan/Work/maven-compiler-test/src/main/java/ProtoStreamContextInitializer.java"
 1 = {java.io.File} "/home/dan/Work/maven-compiler-test/src/main/java/A.java"
{noformat}
 

We have an annotation processor that tries to be smart and doesn't overwrite 
its generated Java source files if they already exists and they have the 
correct checksum. But because the generated file isn't written, it is not added 
to Javac's sources, and Javac does not compile it to a {{.class}} file. I 
haven't tested it, but I believe the same problem appears if the source files 
were generated e.g. by another Maven plugin or by an Ant script in the 
{{generate-sources}} phase.

 

I believe the maven-core behaviour won't change any time soon (and in fact some 
users may depend on the duplicate executions). Instead 
{{org.apache.maven.plugin.compiler.AbstractCompilerMojo#isDependencyChanged()}} 
needs to be fixed to avoid recompilation when runs the second time.



--
This message was sent by Atlassian Jira
(v8.3.4#803005)

Reply via email to