I am writing a simple annotation processor and trying to debug it using eclipse. I created a new project for annotation processor and configured javax.annotation.processing.Processor under META-INF as needed and it processes annotations fine.
Then, I added some more code and tried debugging, but could never make the execution stop at the breakpoints added in the annotation processor. I am compiling using ant and I am using the following ANT options.
export ANT_OPTS="-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000"
After triggering ant build, i go create a remote debug configuration and the debugger starts fine. Ant build also starts successfully. But the execution never stops at any break point added in the annotation processor.
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 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.
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.
In order to enable the same debug experience while compiling using Maven, I setup the POM file as follows:
<dependency>
<groupId>infra</groupId>
<artifactId>annotation-processor</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With