How can I examine the whole source tree with an annotation processor?
I have a lot of handler classes that handle specific message types. To register all these handlers, I need to know which ones exist. Currently, they’re all annotated with a specific annotation, and I use a Java 6 annotation processor to get all of them, and make a Register class that holds an instance of each of the annotated types.
This works great if the whole tree is being built at once, but if just one of the annotated classes is being built (when I save the file in Eclipse, for example), the processor only sees that type, and builds an incomplete Register. How can I examine the other types in this scenario?
2 Solutions collect form web for “How can I examine the whole source tree with an annotation processor?”
I’ve solved this well enough for now. What I did is a little hackey, but basically for every annotated class I see, I add its name to a HashSet. Then I use Filer.getResource() to get open a file where I’ve recorded all the previously-seen annotated classes, and add those to the HashSet too. Then I generate the register class, and write the whole HashSet out to the same resource with Filer.createResource(). This will cause problems if I delete an annotated type, since it will still be recorded in that file, but I can just clean the project or delete that file to solve it.
EDIT: Also, I believe that passing the appropriate “originating elements” to Filer.createSource() should allow Eclipse to track those dependencies properly, but it doesn’t. Perhaps that’s an Eclipse bug.
Unsurprisingly, compile-time annotation processors only process the files being compiled. Eclipse uses incremental compilation to save time, so the short answer is that you cannot expect your annotation processor to see all types in one pass.
One solution is to change your architecture to support incremental compilation. For example, for each annotated
HandlerClass, generate a
RegisterHandlerClass class that registers that handler class.
That said, sounds like what you are doing would be better done at runtime, perhaps with the help of a tool like Reflections.