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:
Annotation Processor developed in a project with GAV:
<groupId>infra</groupId> <artifactId>annotation-processor</artifactId> <version>1.0-SNAPSHOT</version>
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.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 runningjavac
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 ofjavac
. This tells the JVM to suspend execution until the debugger attaches to it.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
orprocess
methods, the debugger will break.In order to enable the same debug experience while compiling using Maven, I setup the POM file as follows:
- 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>
- 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 ofdebugAnnotation
and the definition of the<enableDebugAnnotationCompilerArg>
property. This allows us to start a debugging session of the annotation-processor by runningmvn -P debugAnnotation package
and attaching the eclipse debugger to the compiler process the same way as described in 4 above.- Add a dependency to the POM where the annotation-processor is used: