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?

  • Activity has leaked window$DecorView@44f72ff0 that was originally added here
  • Android sample bluetooth code to send a simple string via bluetooth
  • Maximum size of native heap on Android?
  • java.lang.IllegalStateException what does it mean?
  • Vector drawables that are automatically converted to pngs
  • AsyncTask, must it take such a performance penalty hit…?
  • Related posts:

    Error:Gradle: Execution failed for task ':app:crashlyticsCleanupResourcesDebug'. &...
    Inflate a view / layout into another layout?
    Is there a way to remove the clicking lag on mobile touch devices?
    How to integrate paytm wallet in android application?
    How to call getFragmentManager on Recycler.Adapter?
    What permission I need in order to use camera flash in camera preview?
  • Android Studio SDK location
  • How to set Transparent Background as a Custom Dialog Box in android
  • Why am I getting “Unsupported format” errors, reading H.264 encoded rtsp streams with the Android MediaPlayer?
  • setBackgroundResource() discards my XML layout attributes
  • How to resize Image in Android?
  • RadioButton - how to use a custom drawable?
  • 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.

    Android Babe is a Google Android Fan, All about Android Phones, Android Wear, Android Dev and Android Games Apps and so on.