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