AnnotationProcessor from a dependency does not gets executed

Hi Team,

I am working on a project where I have to migrate from Maven to Gradle (version 7.6). There are some dependencies (jars) which have annotationProcessors declared within them. These annotationProcessors generate some code whenever a new build is created.

These code do not get generated when I create a build with gradle wrapper using the following.

./gradlew clean build

Strangely when I try to build the project using maven using the command

mvn clean build

these annotation processors are executed and I can see the code generated.

Following is a code snippet of the pom file of the jar (let’s call it foo.jar) for the annotation-processor:

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>${maven-compiler-plugin.version}</version>
            <goals>
                <goal>compile</goal>
            </goals>
            <configuration>
                <source>${java.version}</source>
                <target>${java.version}</target>
                <annotationProcessorPaths>
                    <path>
                        <groupId>foo</groupId>
                        <artifactId>foo-annotation-processor</artifactId>
                        <version>${project.version}</version>
                    </path>
                </annotationProcessorPaths>
                <annotationProcessors>
                    <annotationProcessor>foo.annotationprocessor.class1</annotationProcessor>
                    <annotationProcessor>foo.annotationprocessor.class2</annotationProcessor>
                </annotationProcessors>
                <failOnError>true</failOnError>
            </configuration>
        </plugin>
    </plugins>
</build>

The annotation processor class uses the Google AutoService annotation (@AutoService).

The aforementioned jar is imported as a dependency in the pom.xml.

I have tried to follow the same in the build.gradle with the following dependecies:

implementation("com.google.auto.service:auto-service-annotations:1.0.1")
annotationProcessor("com.google.auto.service:auto-service:1.0.1")

implementation("foo.jar")
annotationProcessor("foo.jar")

But for some reason the annotation processors do not get executed. Can someone please help me with this issue? I am not sure what I am missing here.

You might have crippled your build too much maybe to post it here.
Because implementation("foo.jar") and annotationProcessor("foo.jar") for example will not work.
Can you maybe knit an MCVE that demonstrates your problem?

Sidenote: Don’t adopt the practice of always calling clean from Maven. With Maven projects this is usually necessary to get clean reproducible and correct builds. With Gradle the only thing you gain is a waste of time as you prevent any up-to-date logic. Because Gradle is pretty good in avoiding unnecessary work if you let it. If you need to do clean to get correct builds, there is most probably something wrong with your build script or you use some broken plugin.

Sure, thank you. Let me try to reiterate my problem. I have a jar file (name: test-annotation-processor.jar) which has the annotation-processors declared. The annotation-processors have the following format:

@SupportedAnnotationTypes("*")
@SupportedSourceVersion(SourceVersion.RELEASE_11)
@AutoService(Processor.class)
@SuppressWarnings("unused")
public class TestGenerator extends AbstractProcessor {
    
    @Override
    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
        //Searches for classes marked with specific annotations (example: @TestAnnotation)
        //Generates code classes
    }
}

//Annotation Class
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
public @interface TestAnnotation {
  //Supporting methods
}

pom.xml of this jar is shared in the question above

The above jar is used as a dependency in another project’s pom.xml as:

 <dependency>
    <groupId>test.annotation.processor</groupId>
    <artifactId>test-annotation-processor</artifactId>
    <version>${version}</version>
</dependency>

Whenever I create a new build using Maven (using maven clean install), the annotation processor kicks in and the code gets generated in the folder at the following path:

${project-root}/target/generated-sources/annotations/

I am trying to migrate this pom.xml to a build.gradle file. My build.gradle.kts has the following structure:

plugins {
    id("maven-publish")
    id("java-library")
}

dependencies {
    implementation("test.annotation.processor:test-annotation-processor:version")
    annotationProcessor("test.annotation.processor:test-annotation-processor:version")
   //Other dependencies
}

When I try to create a build using gradle clean build, I can see the folder structure which gets generated but unfortunately the folder is empty and no code gets generated. I tried to attach a debug point to the annotation-processor but was never able to reach it. I am guessing that the annotation-processor does gets executed in this case:

${project-root}/build/generated/sources/annotationProcessor/java/main

I tried to check if the annotation-processing jar is available in the classpath using the command:
./gradlew dependencies --configuration runtimeClasspath
and I found them to be available.

In Intellij, I was also able to check the presence of this jar in the external dependencies section. It had the following structure:

| - jar
    | - package
        | - Annotation Processor Classes
    | - META-INF
      - Other packages
      - services
         - javax.annotation.processing.Processor

The file javax.annotation.processing.Processor contains the fully qualified name of the annotation-processor class.

Please let me know if anymore information is required from my end.

The implementation(...) should not be necessary, unless there are also classes in the jar that you compile against and need at runtime.
If there are classes in there you do not compile against but need at runtime, you could add it to runtimeOnly(...) instead.
If there are classes - like annotations - in there you need at compile time, but not at runtime, you could add it to compileOnly(...) instead.
If the files inside the jar are neither needed at compile time, nor runtime, you don’t need it at all.

Adding it to annotationProcessor(...) should be enough for the annotation processor to kick in.
If you for example add

compileOnly("javax:javaee-api:8.0.1")
annotationProcessor("org.hibernate:hibernate-validator-annotation-processor:5.2.5.Final")

to your dependencies and annotate a boolean field with @Valid, then compileJava fails due to the validation the annotation processor is doing.

For debugging the annotation processor, you have to debug the actual java compiler execution. For this use

tasks.compileJava {
    options.isFork = true
    options.forkOptions.jvmArgs!!.add("-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=5005")
}

and then attach the debugger to port 5005 once the compiler waits for the debugger.

Thank you for sharing. Let me try this.