Debugging Annotation processors in eclipse

The easiest way is to create an eclipse plugin and then debug it directly from eclipse. It sound a lot harder then it is - this: https://www.youtube.com/watch?v=PjUaHkUsgzo is a 7 minute guide in youtube that can get you started.


This is a problem I just ran into, and the eclipse plugin solution seems super cumbersome to me. I found a simpler solution using javax.tools.JavaCompiler to invoke the compilation process. Using the code below, you can just Right-Click > Debug As > JUnit Test in eclipse and debug you annotation processor directly from there

   @Test
   public void runAnnoationProcessor() throws Exception {
      String source = "my.project/src";

      Iterable<JavaFileObject> files = getSourceFiles(source);

      JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();

      CompilationTask task = compiler.getTask(new PrintWriter(System.out), null, null, null, null, files);
      task.setProcessors(Arrays.asList(new MyAnnotationProcessorClass()));

      task.call();
   }

   private Iterable<JavaFileObject> getSourceFiles(String p_path) throws Exception {
     JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
     StandardJavaFileManager files = compiler.getStandardFileManager(null, null, null);

     files.setLocation(StandardLocation.SOURCE_PATH, Arrays.asList(new File(p_path)));

     Set<Kind> fileKinds = Collections.singleton(Kind.SOURCE);
     return files.list(StandardLocation.SOURCE_PATH, "", fileKinds, true);
   }

This question has been posted over 6 years ago, however, I ran into the same problem now and still couldn't find a good answer on the Internet.

I was finally able to work out a good setup that allows me to develop an Annotation Processor, use it in compilation of another project, and debug it as needed.

The setup is like this:

  1. Annotation Processor developed in a project with GAV:

    <groupId>infra</groupId> <artifactId>annotation-processor</artifactId> <version>1.0-SNAPSHOT</version>

  2. In the annotation-processor POM file I specified the following:

    <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>${maven.compiler.plugin.version}</version> <configuration> <compilerArgument>-proc:none</compilerArgument> <source>${java.source.version}</source> <target>${java.source.version}</target> <encoding>UTF-8</encoding> </configuration> </plugin> </plugins> </build>

    Notice the <compilerArgument>-proc:none</compilerArgument> specification.

  3. In the project where the annotation-processor is used, it is used during the compilation of the project. I.e. the annotation-processor is invoked during the execution of the compiler, javac. I found that in order to debug the annotation-processor execution while running javac directly, I can use the following command line:

    javac -J-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=1044 -d target/classes -proc:only -processor infra.annotation.CustomizationAnnotationProcessor -cp ../annotation-processor/target/annotation-processor-1.0-SNAPSHOT.jar src\main\java\org\digital\annotationtest\MyTestClass.java

    Notice the suspend=y part in the command line of javac. This tells the JVM to suspend execution until the debugger attaches to it.

  4. In this situation, I can start the eclipse debugger by starting a Remote Java Application Debug Configuration. Configure it to use the annotation-processor project, and attach to the process on localhost and port 1044. this allows you to debug the annotation processor code. If you set a breakpoint in the init or process methods, the debugger will break.

  5. In order to enable the same debug experience while compiling using Maven, I setup the POM file as follows:

    1. Add a dependency to the POM where the annotation-processor is used: <dependency> <groupId>infra</groupId> <artifactId>annotation-processor</artifactId> <version>1.0-SNAPSHOT</version> </dependency>
    2. In the same project using the annotation-processor define the following:

    <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>${maven.compiler.plugin.version}</version> <configuration> <source>1.8</source> <target>1.8</target> <fork>true</fork> <compilerArgs> <compilerArg>-J-verbose</compilerArg> <compilerArg>${enableDebugAnnotationCompilerArg}</compilerArg> </compilerArgs> <forceJavacCompilerUse>true</forceJavacCompilerUse> <annotationProcessorPaths> <annotationProcessorPath> <groupId>infra</groupId> <artifactId>annotation-processor</artifactId> <version>1.0-SNAPSHOT</version> </annotationProcessorPath> </annotationProcessorPaths> <annotationProcessors> <annotationProcessor>infra.annotation.CustomizationAnnotationProcessor</annotationProcessor> </annotationProcessors> </configuration> </plugin> </plugins> </build> <profiles> <profile> <id>debugAnnotation</id> <properties> <enableDebugAnnotationCompilerArg>-J-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=1044</enableDebugAnnotationCompilerArg> </properties> </profile> </profiles>

    Notice the use of <fork>true</fork>, and <compilerArg>${enableDebugAnnotationCompilerArg}</compilerArg>.
    Also, notice the profile deinition of debugAnnotation and the definition of the <enableDebugAnnotationCompilerArg> property. This allows us to start a debugging session of the annotation-processor by running mvn -P debugAnnotation package and attaching the eclipse debugger to the compiler process the same way as described in 4 above.