Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to step-debug annotation processor during compile?

I have an annotation processor for an annotation of retention policy=SOURCE.

I have not idea how to step-debug it.

  • I have issued print statements, logger info when I run mvn install, compile or package or ant javac, and I see their sysouts in the compile log.

  • However, I have no idea how to step-debug the processor in Eclipse. I mean, how do you step-debug compile-time?

like image 220
Blessed Geek Avatar asked Oct 04 '12 19:10

Blessed Geek


People also ask

How do I run an annotation processor?

Settings -> Build, Execution, Deployment -> Compiler -> Annotation Processors -> Enable Annotation Processing.

What is the annotation process?

Annotating is any action that deliberately interacts with a text to enhance the reader's understanding of, recall of, and reaction to the text. Sometimes called "close reading," annotating usually involves highlighting or underlining key pieces of text and making notes in the margins of the text.

How do I enable JPS incremental annotation processing?

Navigate to Build, Execution, Deployment > Compiler > Annotation Processors. Make sure "Enable annotation processing".

What is annotation processing tool?

Annotation processing is a tool built into javac for scanning and processing annotations at compile time. It can create new source files; however, it can't modify existing ones. It's done in rounds. The first round starts when the compilation reaches the pre-compile phase.


3 Answers

An option in recent times is to use something like http://github.com/google/compile-testing which lets you invoke the compilation job against arbitrary annotation processors, which you can set break points, step through, etc.

@Test public void testStuff() {
  // Create a source file to process, or load one from disk.
  JavaFileObject file = JavaFileObjects.fromSourceLines("test.Foo",
    "package test;",
    "",
    "import bar.*;",
    "",
    "@MyAnnotation(blah=false)",
    "interface TestInterface {",
    "  Bar someBar();",
    "}",

  // assert conditions following a compilation in the context of MyProcessor.
  assert_().about(javaSource()).that(file)
      .processedWith(new MyProcessor())
      .failsToCompile()
      .withErrorContaining("some error message").in(file).onLine(5);
}

This test expects you will get some error message because @MyAnnotation is incorrectly declared in the test data source. If this assertion fails, you can run it in debug mode in your IDE, set breakpoints in MyProcessor, and step through with a full compiler environment active during debugging.

For unit testing specific methods within your processor, you can also use the @Rule called CompilationRule from which you can obtain Elements and Types utility classes in order to test specific logic in your compiler in a more isolated way.

like image 55
Christian Gruber Avatar answered Oct 15 '22 20:10

Christian Gruber


Annotation processing occurs during compilation, so normal debugging won't work. If you want to debug it in the context of you project, you can use Eclipse remote debugging, while having Gradle or Maven in debug mode. Then you can put breakpoints in the Annotation Processor's files.

See Debugging an Annotation Processor in any project.

Disclaimer: I wrote the post.

like image 39
bryant1410 Avatar answered Oct 15 '22 19:10

bryant1410


You have to invoke the Java compiler from Eclipse, using a debug configuration (you'll need to create the configuration manually, from the "Debug Configurations..." menu choice.

The "correct" way to invoke the Java compiler under JDK 1.6 or above is to use the JavaCompiler interface in javax.tools, which you get from the ToolProvider (I include all the links because there's a decent amount of class/package documentation that you should read).

The "quick-and-dirty" way (that should work, but I make no guarantees) is to invoke com.sun.tools.javac.Main.main(), passing it your normal command-line arguments. To do this, you'll need tools.jar on your classpath (it's found in $JAVA_HOME/lib).

like image 20
parsifal Avatar answered Oct 15 '22 19:10

parsifal