Search code examples
javaannotationsannotation-processing

Consistency of processing environment members across compilation rounds


The Java Annotation Processing API as it stands in JDK 6 and 7 (not the apt tool API from 5) defines the lifecycle of an annotation processor. One is instantiated via the no-args constructor, the init method is called with a ProcessingEnvironment instance and then that processor is used via the process method. Only one instance of the processor is made and used throughout all subsequent processing rounds if applicable.

Since my processor class was getting a bit bloated, I've created handler classes for separate annotations it's supposed to deal with. In the methods of those classes I'm always passing in Elements and Types instances that I've obtained from the ProcessingEnvironment for their utility methods. This is making my method signatures rather long.

I'd rather just keep a reference to the Elements and Types instances in the handlers, as well as in the processor instance. I've done this by getting them from the ProcessingEnvironment passed into the init method. Now, I'm wondering if this is safe. The JavaDoc for Processor makes it clear that some methods are only called once for a processor, but init isn't mentioned here. I was kind of assuming this is implicitly understood, but I'm not 100% certain.

I'd also like to know if the Messager instance, which can be obtained from ProcessingEnvironment as well, remains the same across all processing rounds. I'd rather not have warnings/errors from one round showing up but others getting left out. I'm reasonably certain that it should be safe to use the same instances across rounds, but just would like some certainty.


Solution

  • I've asked myself the same question and decided to always use the current round's ProcessingEnvironment's utilities provided by init. There doesn't seem to be any difference when using javac, but there are other annotation processing tools which may show different behaviour. I've already experienced a few differences between the processing tool in javac and the one used by eclipse, so I handle anything not explicit in the documentation with great care. The question is, do you want test all existing processing tools?

    Also, I think if those processing helper tools were meant to never change, they would be arguments of the processor's constructor.