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

Rick Ossendrijver updated MCOMPILER-503:
----------------------------------------
    Description: 
This issue relates to MCOMPILER-272. That ticket improved annotation processor 
classpath construction, but as of version 3.10.1 the constructed classpath is 
still highly unintuitive.

In a nutshell, the generated annotation processor classpath does not match 
Maven's "general" dependency resolution logic, leading to (at least) the 
following issues:
 - The classpath may contain multiple versions of the same dependency.
 - Indirect dependencies may take precedence over explicitly declared 
dependencies.

h1. Reproduction case

Consider a {{pom.xml}} with a {{maven-compiler-plugin}} configuration as 
follows: 
{code:xml}
<annotationProcessorPaths>
    <path>
        <groupId>com.google.auto.service</groupId>
        <artifactId>auto-service</artifactId>
        <version>1.0</version>
    </path>
    <path>
        <groupId>com.google.guava</groupId>
        <artifactId>guava</artifactId>
        <version>31.0.1-jre</version>
    </path>
</annotationProcessorPaths> {code}
Note that {{com.google.auto.service:auto-service}} 1.0 depends on Guava 
30.1.1-jre, which is a different version of Guava than the one explicitly 
specified. 

The generated annotation processor classpath is output when executing {{{}mvn 
clean install -X{}}}. We can extract it as follows:
{code:sh}
mvn clean install -X | grep -oP '(?<=-processorpath )\S+' | xargs -d: -l1 {code}
As of version 3.9.0+ this outputs:
{code:sh}
/home/user/.m2/repository/com/google/auto/service/auto-service/1.0/auto-service-1.0.jar
/home/user/.m2/repository/com/google/auto/service/auto-service-annotations/1.0/auto-service-annotations-1.0.jar
/home/user/.m2/repository/com/google/auto/auto-common/1.0/auto-common-1.0.jar
/home/user/.m2/repository/com/google/guava/guava/30.1.1-jre/guava-30.1.1-jre.jar
/home/user/.m2/repository/com/google/guava/failureaccess/1.0.1/failureaccess-1.0.1.jar
/home/user/.m2/repository/com/google/guava/listenablefuture/9999.0-empty-to-avoid-conflict-with-guava/listenablefuture-9999.0-empty-to-avoid-conflict-with-guava.jar
/home/user/.m2/repository/com/google/code/findbugs/jsr305/3.0.2/jsr305-3.0.2.jar
/home/user/.m2/repository/org/checkerframework/checker-qual/3.8.0/checker-qual-3.8.0.jar
/home/user/.m2/repository/com/google/errorprone/error_prone_annotations/2.5.1/error_prone_annotations-2.5.1.jar
/home/user/.m2/repository/com/google/j2objc/j2objc-annotations/1.3/j2objc-annotations-1.3.jar
/home/user/.m2/repository/com/google/guava/guava/31.0.1-jre/guava-31.0.1-jre.jar
/home/user/.m2/repository/org/checkerframework/checker-qual/3.12.0/checker-qual-3.12.0.jar
/home/user/.m2/repository/com/google/errorprone/error_prone_annotations/2.7.1/error_prone_annotations-2.7.1.jar{code}
Note the following:
 - Some dependencies are duplicated, with _different versions_ listed 
({{{}guava{}}}, {{{}checker-qual{}}}, and {{{}error_prone_annotations{}}}).
 - Even though the {{pom.xml}} explicitly declares a dependency on Guava 
31.0.1-jre, the classpath lists version 30.1.1-jre first, meaning that de
  facto the latter will be used.

In practice this means that:
 # One cannot rely on "common Maven dependency resolution knowledge".
 # One must be very careful with the order in which dependencies are listed.
 # The need to carefully order the dependencies may mean that a certain 
configuration cannot be factored out to a Maven profile.

Ideally {{annotationProcessorPaths}} follows the same dependency resolution 
logic as "regular" project dependencies. That is, ideally the classpath would 
be constructed as follows (this is what {{mvn dependency:build-classpath}} 
would output if the aforementioned artifacts were declared as "regular" build 
dependencies):
{code:sh}
/home/user/.m2/repository/com/google/auto/service/auto-service/1.0/auto-service-1.0.jar
/home/user/.m2/repository/com/google/auto/service/auto-service-annotations/1.0/auto-service-annotations-1.0.jar
/home/user/.m2/repository/com/google/auto/auto-common/1.0/auto-common-1.0.jar
/home/user/.m2/repository/com/google/guava/guava/31.0.1-jre/guava-31.0.1-jre.jar
/home/user/.m2/repository/com/google/guava/failureaccess/1.0.1/failureaccess-1.0.1.jar
/home/user/.m2/repository/com/google/guava/listenablefuture/9999.0-empty-to-avoid-conflict-with-guava/listenablefuture-9999.0-empty-to-avoid-conflict-with-guava.jar
/home/user/.m2/repository/com/google/code/findbugs/jsr305/3.0.2/jsr305-3.0.2.jar
/home/user/.m2/repository/org/checkerframework/checker-qual/3.12.0/checker-qual-3.12.0.jar
/home/user/.m2/repository/com/google/errorprone/error_prone_annotations/2.7.1/error_prone_annotations-2.7.1.jar
/home/user/.m2/repository/com/google/j2objc/j2objc-annotations/1.3/j2objc-annotations-1.3.jar{code}
—
We would like your input on this issue. 
[This|https://github.com/PicnicSupermarket/maven-compiler-plugin-issue-503] 
GitHub project contains a minimal reproduction case. We are open to feedback 
and willing to propose a PR to resolve this issue.

  was:
This issue relates to MCOMPILER-272. That ticket improved annotation processor 
classpath construction, but as of version 3.10.1 the constructed classpath is 
still highly unintuitive.

In a nutshell, the generated annotation processor classpath does not match 
Maven's "general" dependency resolution logic, leading to (at least) the 
following issues:
 - The classpath may contain multiple versions of the same dependency.
 - Indirect dependencies may take precedence over explicitly declared
  dependencies.

h1. Reproduction case

Consider a `pom.xml` with a `maven-compiler-plugin` configuration as follows:
{code:xml}
<annotationProcessorPaths>
    <path>
        <groupId>com.google.auto.service</groupId>
        <artifactId>auto-service</artifactId>
        <version>1.0</version>
    </path>
    <path>
        <groupId>com.google.guava</groupId>
        <artifactId>guava</artifactId>
        <version>31.0.1-jre</version>
    </path>
</annotationProcessorPaths> {code}
Note that `com.google.auto.service:auto-service` 1.0 depends on Guava 
30.1.1-jre, which is a different version of Guava than the one explicitly 
specified. 

The generated annotation processor classpath is output when executing `mvn 
clean install -X`. We can extract it as follows:
{code:sh}
mvn clean install -X | grep -oP '(?<=-processorpath )\S+' | xargs -d: -l1 {code}
As of version 3.9.0+ this outputs:
{code:sh}
/home/user/.m2/repository/com/google/auto/service/auto-service/1.0/auto-service-1.0.jar
/home/user/.m2/repository/com/google/auto/service/auto-service-annotations/1.0/auto-service-annotations-1.0.jar
/home/user/.m2/repository/com/google/auto/auto-common/1.0/auto-common-1.0.jar
/home/user/.m2/repository/com/google/guava/guava/30.1.1-jre/guava-30.1.1-jre.jar
/home/user/.m2/repository/com/google/guava/failureaccess/1.0.1/failureaccess-1.0.1.jar
/home/user/.m2/repository/com/google/guava/listenablefuture/9999.0-empty-to-avoid-conflict-with-guava/listenablefuture-9999.0-empty-to-avoid-conflict-with-guava.jar
/home/user/.m2/repository/com/google/code/findbugs/jsr305/3.0.2/jsr305-3.0.2.jar
/home/user/.m2/repository/org/checkerframework/checker-qual/3.8.0/checker-qual-3.8.0.jar
/home/user/.m2/repository/com/google/errorprone/error_prone_annotations/2.5.1/error_prone_annotations-2.5.1.jar
/home/user/.m2/repository/com/google/j2objc/j2objc-annotations/1.3/j2objc-annotations-1.3.jar
/home/user/.m2/repository/com/google/guava/guava/31.0.1-jre/guava-31.0.1-jre.jar
/home/user/.m2/repository/org/checkerframework/checker-qual/3.12.0/checker-qual-3.12.0.jar
/home/user/.m2/repository/com/google/errorprone/error_prone_annotations/2.7.1/error_prone_annotations-2.7.1.jar{code}
 

Note the following:
 - Some dependencies are duplicated, with _different versions_ listed (`guava`, 
`checker-qual`, and `error_prone_annotations`).
 - Even though the `pom.xml` explicitly declares a dependency on Guava 
31.0.1-jre, the classpath lists version 30.1.1-jre first, meaning that de
  facto the latter will be used.

In practice this means that:
 # One cannot rely on "common Maven dependency resolution knowledge".
 # One must be very careful with the order in which dependencies are listed.
 # The need to carefully order the dependencies may mean that a certain 
configuration cannot be factored out to a Maven profile.

Ideally `annotationProcessorPaths` follows the same dependency resolution logic 
as "regular" project dependencies. That is, ideally the classpath would be 
constructed as follows (this is what `mvn dependency:build-classpath` would 
output if the aforementioned artifacts were declared as "regular" build 
dependencies):
{code:sh}
/home/user/.m2/repository/com/google/auto/service/auto-service/1.0/auto-service-1.0.jar
/home/user/.m2/repository/com/google/auto/service/auto-service-annotations/1.0/auto-service-annotations-1.0.jar
/home/user/.m2/repository/com/google/auto/auto-common/1.0/auto-common-1.0.jar
/home/user/.m2/repository/com/google/guava/guava/31.0.1-jre/guava-31.0.1-jre.jar
/home/user/.m2/repository/com/google/guava/failureaccess/1.0.1/failureaccess-1.0.1.jar
/home/user/.m2/repository/com/google/guava/listenablefuture/9999.0-empty-to-avoid-conflict-with-guava/listenablefuture-9999.0-empty-to-avoid-conflict-with-guava.jar
/home/user/.m2/repository/com/google/code/findbugs/jsr305/3.0.2/jsr305-3.0.2.jar
/home/user/.m2/repository/org/checkerframework/checker-qual/3.12.0/checker-qual-3.12.0.jar
/home/user/.m2/repository/com/google/errorprone/error_prone_annotations/2.7.1/error_prone_annotations-2.7.1.jar
/home/user/.m2/repository/com/google/j2objc/j2objc-annotations/1.3/j2objc-annotations-1.3.jar{code}
—
We would like your input on this issue. 
[This|https://github.com/PicnicSupermarket/maven-compiler-plugin-issue-503] 
GitHub project contains a minimal reproduction case. We are open to feedback 
and willing to propose a PR to resolve this issue.


> Unexpected dependency resolution of `annotationProcessorPaths`
> --------------------------------------------------------------
>
>                 Key: MCOMPILER-503
>                 URL: https://issues.apache.org/jira/browse/MCOMPILER-503
>             Project: Maven Compiler Plugin
>          Issue Type: Bug
>    Affects Versions: 3.10.1
>            Reporter: Rick Ossendrijver
>            Priority: Major
>
> This issue relates to MCOMPILER-272. That ticket improved annotation 
> processor classpath construction, but as of version 3.10.1 the constructed 
> classpath is still highly unintuitive.
> In a nutshell, the generated annotation processor classpath does not match 
> Maven's "general" dependency resolution logic, leading to (at least) the 
> following issues:
>  - The classpath may contain multiple versions of the same dependency.
>  - Indirect dependencies may take precedence over explicitly declared 
> dependencies.
> h1. Reproduction case
> Consider a {{pom.xml}} with a {{maven-compiler-plugin}} configuration as 
> follows: 
> {code:xml}
> <annotationProcessorPaths>
>     <path>
>         <groupId>com.google.auto.service</groupId>
>         <artifactId>auto-service</artifactId>
>         <version>1.0</version>
>     </path>
>     <path>
>         <groupId>com.google.guava</groupId>
>         <artifactId>guava</artifactId>
>         <version>31.0.1-jre</version>
>     </path>
> </annotationProcessorPaths> {code}
> Note that {{com.google.auto.service:auto-service}} 1.0 depends on Guava 
> 30.1.1-jre, which is a different version of Guava than the one explicitly 
> specified. 
> The generated annotation processor classpath is output when executing {{{}mvn 
> clean install -X{}}}. We can extract it as follows:
> {code:sh}
> mvn clean install -X | grep -oP '(?<=-processorpath )\S+' | xargs -d: -l1 
> {code}
> As of version 3.9.0+ this outputs:
> {code:sh}
> /home/user/.m2/repository/com/google/auto/service/auto-service/1.0/auto-service-1.0.jar
> /home/user/.m2/repository/com/google/auto/service/auto-service-annotations/1.0/auto-service-annotations-1.0.jar
> /home/user/.m2/repository/com/google/auto/auto-common/1.0/auto-common-1.0.jar
> /home/user/.m2/repository/com/google/guava/guava/30.1.1-jre/guava-30.1.1-jre.jar
> /home/user/.m2/repository/com/google/guava/failureaccess/1.0.1/failureaccess-1.0.1.jar
> /home/user/.m2/repository/com/google/guava/listenablefuture/9999.0-empty-to-avoid-conflict-with-guava/listenablefuture-9999.0-empty-to-avoid-conflict-with-guava.jar
> /home/user/.m2/repository/com/google/code/findbugs/jsr305/3.0.2/jsr305-3.0.2.jar
> /home/user/.m2/repository/org/checkerframework/checker-qual/3.8.0/checker-qual-3.8.0.jar
> /home/user/.m2/repository/com/google/errorprone/error_prone_annotations/2.5.1/error_prone_annotations-2.5.1.jar
> /home/user/.m2/repository/com/google/j2objc/j2objc-annotations/1.3/j2objc-annotations-1.3.jar
> /home/user/.m2/repository/com/google/guava/guava/31.0.1-jre/guava-31.0.1-jre.jar
> /home/user/.m2/repository/org/checkerframework/checker-qual/3.12.0/checker-qual-3.12.0.jar
> /home/user/.m2/repository/com/google/errorprone/error_prone_annotations/2.7.1/error_prone_annotations-2.7.1.jar{code}
> Note the following:
>  - Some dependencies are duplicated, with _different versions_ listed 
> ({{{}guava{}}}, {{{}checker-qual{}}}, and {{{}error_prone_annotations{}}}).
>  - Even though the {{pom.xml}} explicitly declares a dependency on Guava 
> 31.0.1-jre, the classpath lists version 30.1.1-jre first, meaning that de
>   facto the latter will be used.
> In practice this means that:
>  # One cannot rely on "common Maven dependency resolution knowledge".
>  # One must be very careful with the order in which dependencies are listed.
>  # The need to carefully order the dependencies may mean that a certain 
> configuration cannot be factored out to a Maven profile.
> Ideally {{annotationProcessorPaths}} follows the same dependency resolution 
> logic as "regular" project dependencies. That is, ideally the classpath would 
> be constructed as follows (this is what {{mvn dependency:build-classpath}} 
> would output if the aforementioned artifacts were declared as "regular" build 
> dependencies):
> {code:sh}
> /home/user/.m2/repository/com/google/auto/service/auto-service/1.0/auto-service-1.0.jar
> /home/user/.m2/repository/com/google/auto/service/auto-service-annotations/1.0/auto-service-annotations-1.0.jar
> /home/user/.m2/repository/com/google/auto/auto-common/1.0/auto-common-1.0.jar
> /home/user/.m2/repository/com/google/guava/guava/31.0.1-jre/guava-31.0.1-jre.jar
> /home/user/.m2/repository/com/google/guava/failureaccess/1.0.1/failureaccess-1.0.1.jar
> /home/user/.m2/repository/com/google/guava/listenablefuture/9999.0-empty-to-avoid-conflict-with-guava/listenablefuture-9999.0-empty-to-avoid-conflict-with-guava.jar
> /home/user/.m2/repository/com/google/code/findbugs/jsr305/3.0.2/jsr305-3.0.2.jar
> /home/user/.m2/repository/org/checkerframework/checker-qual/3.12.0/checker-qual-3.12.0.jar
> /home/user/.m2/repository/com/google/errorprone/error_prone_annotations/2.7.1/error_prone_annotations-2.7.1.jar
> /home/user/.m2/repository/com/google/j2objc/j2objc-annotations/1.3/j2objc-annotations-1.3.jar{code}
> —
> We would like your input on this issue. 
> [This|https://github.com/PicnicSupermarket/maven-compiler-plugin-issue-503] 
> GitHub project contains a minimal reproduction case. We are open to feedback 
> and willing to propose a PR to resolve this issue.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to