TheMrMilchmann / gradle-ecj

A Gradle plugin for using the Eclipse Compiler for Java (ECJ) for compiling Java files.
https://plugins.gradle.org/plugin/io.github.themrmilchmann.ecj
MIT License
10 stars 2 forks source link

How do I configure Annotation Processing with this plugin? #30

Open Chessray opened 3 months ago

Chessray commented 3 months ago

Hello,

Thank you for providing this plugin.

Background: One of my users reported an error when compiling a project that uses one particular feature in MapStruct Spring Extensions using Eclipse. Turns out that ECJ handles one part of the annotation processing differently to Javac (but still spec-compliant). So obviously I'd like to fix this and found this plugin which I'd like to help me in reproducing the error. However, it already fails on a previous hurdle. I configured it in this example.

Building the example results in this error:

> Task :examples:external-conversions:compileJava FAILED
----------
1. ERROR in /Users/raimundklein/development/GitHub/mapstruct-spring-extension/examples/external-conversions/src/main/java/org/mapstruct/extensions/spring/example/externalconversions/LocaleInfoDtoMapper.java (at line 6)
    @Mapper(config = MapstructConfig.class, uses = ConversionServiceAdapter.class)
                                                   ^^^^^^^^^^^^^^^^^^^^^^^^
ConversionServiceAdapter cannot be resolved to a type
----------
1 problem (1 error)

The "missing" class is generated during annotation processing. Please note that this part works well inside Eclipse if I remove the @ExternalConversion section which is the one reported as erroneous. If I remove the plugin and use Javac instead, everything is fine. Do I need to add another line for annotation processing, and if so which one?

TheMrMilchmann commented 3 months ago

Hi @Chessray, I reproduced the issue and can confirm that annotation processors do not work correctly with this plugin. Specifically, no code is generated despite the processors being recognized. I don't know what is causing this issue yet and, unfortunately, I probably won't get around to investigating this until the end of the month.

I've found that a quick (but dirty) fix might be adding the processor to the compileOnly configuration. So, for example

    compileOnly("org.mapstruct:mapstruct-processor:1.5.5.Final")
    annotationProcessor("org.mapstruct:mapstruct-processor:1.5.5.Final")

works.


Here are some clues:

With ECJ (without compile dependency):

Round 1:
    input files: {org.mapstruct.example.SourceTargetMapper,org.mapstruct.example.Target,org.mapstruct.example.Foobar,org.mapstruct.example.Source}
    annotations: [org.mapstruct.Mappings,org.mapstruct.InheritInverseConfiguration,org.mapstruct.Mapper]
    last round: false
Round 2:
    input files: {}
    annotations: []
    last round: true

With ECJ (with compile dependency):

Round 1:
    input files: {org.mapstruct.example.SourceTargetMapper,org.mapstruct.example.Target,org.mapstruct.example.Foobar,org.mapstruct.example.Source}
    annotations: [org.mapstruct.Mappings,org.mapstruct.InheritInverseConfiguration,org.mapstruct.Mapper]
    last round: false
Discovered processor service org.mapstruct.ap.MappingProcessor
  supporting [org.mapstruct.Mapper]
  in jar:file:/C:/Users/linha/.gradle/caches/modules-2/files-2.1/org.mapstruct/mapstruct-processor/1.5.5.Final/897f6f115930b936287bef552bf5fe28cc64717d/mapstruct-processor-1.5.5.Final.jar!/
Processor org.mapstruct.ap.MappingProcessor matches [org.mapstruct.Mapper] and returns false
Round 2:
    input files: {org.mapstruct.example.SourceTargetMapperImpl}
    annotations: [javax.annotation.processing.Generated,java.lang.Override]
    last round: false
Processor org.mapstruct.ap.MappingProcessor matches [] and returns false
Round 3:
    input files: {}
    annotations: []
    last round: true

With Javac:

Round 1:
    input files: {org.mapstruct.example.Foobar, org.mapstruct.example.Source, org.mapstruct.example.SourceTargetMapper, org.mapstruct.example.Target}
    annotations: [org.mapstruct.Mapper, org.mapstruct.Mappings, org.mapstruct.InheritInverseConfiguration]
    last round: false
Processor org.gradle.api.internal.tasks.compile.processing.TimeTrackingProcessor matches [/org.mapstruct.Mapper] and returns false.
Processor org.gradle.api.internal.tasks.compile.processing.SupportedOptionsCollectingProcessor matches [/org.mapstruct.Mappings, /org.mapstruct.Mapper, /org.mapstruct.InheritInverseConfiguration] and returns false.
Round 2:
    input files: {org.mapstruct.example.SourceTargetMapperImpl}
    annotations: [javax.annotation.processing.Generated, java.lang.Override]
    last round: false
Processor org.gradle.api.internal.tasks.compile.processing.TimeTrackingProcessor matches [] and returns false.
Processor org.gradle.api.internal.tasks.compile.processing.SupportedOptionsCollectingProcessor matches [java.compiler/javax.annotation.processing.Generated, java.base/java.lang.Override] and returns false.
Round 3:
    input files: {}
    annotations: []
    last round: true