You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@maven.apache.org by "Guillaume Nodet (Jira)" <ji...@apache.org> on 2023/02/14 07:49:00 UTC

[jira] [Closed] (MCOMPILER-433) mvn clean compile test compiles the source files twice

     [ https://issues.apache.org/jira/browse/MCOMPILER-433?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Guillaume Nodet closed MCOMPILER-433.
-------------------------------------
      Assignee: Guillaume Nodet  (was: Olivier Lamy)
    Resolution: Fixed

> 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
>            Assignee: Guillaume Nodet
>            Priority: Major
>             Fix For: 3.11.0
>
>
> 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.20.10#820010)