如何使用注解处理器检查整个源代码树?

12

我有很多处理程序类来处理特定的消息类型。为了注册所有这些处理程序,我需要知道哪些已存在。目前它们都用特定注释进行了注释,并且我使用Java 6注释处理器获取所有这些注释,并创建一个Register类,该类保存每个注释类型的实例。

如果整个树正在同时构建,则此方法非常有效,但是如果仅正在构建其中一个注释类(例如在Eclipse中保存文件时),处理器只会看到该类型,并构建一个不完整的Register。在此情况下,我如何检查其他类型?


你使用的是哪个注解处理器? - Garrett Hall
我自己写的,使用Java 6 API(扩展javax.annotation.processing.AbstractProcessor) - Tavian Barnes
根据我的调查,这似乎不可用,但如果有的话,我真的很想知道。 - John Ericksen
我在想,当Eclipse导出apk时,它是否会重新编译整个源代码树? - John Ericksen
2个回答

6
我已经暂时解决了这个问题。我的做法有点hackey,但基本上是遇到每个注释类就将其名称添加到HashSet中。然后我使用Filer.getResource()打开一个文件,在其中记录了所有之前看过的注释类,并将它们也添加到HashSet中。然后我生成注册类,并使用Filer.createResource()将整个HashSet写入相同的资源中。如果我删除了一个注释类型,这将会导致问题,因为它仍将在那个文件中记录,但我可以清理项目或删除该文件来解决它。
另外,我认为将适当的“起源元素”传递给Filer.createSource()应该允许Eclipse正确跟踪这些依赖关系,但它没有。也许这是一个Eclipse的bug。

你是否有在任何地方分享这段代码?我对你的方法很感兴趣。 - John Ericksen
这是公司拥有的代码,但如果我为个人项目编写类似的东西,它将可用。 - Tavian Barnes
我已经为此编写了一个通用库。我找到了这个页面,因为我的库也遇到了同样的问题... - Sławek
太棒了,我一直想做这个但从未有时间。我会试一试的。 - Tavian Barnes

1

毫不意外,编译时注解处理器只处理正在编译的文件。Eclipse使用增量编译来节省时间,因此简短的答案是你不能期望你的注解处理器在一次处理中看到所有类型。

一个解决方案是改变你的架构以支持增量编译。例如,对于每个已注解的HandlerClass,生成一个RegisterHandlerClass类来注册该处理程序类。

尽管如此,你正在进行的工作似乎最好在运行时完成,可能需要使用像Reflections这样的工具。


1
这是Android代码,看起来大多数框架在Android上不起作用;无论如何,如果可能的话,我想尽量避免类路径扫描。如果我选择使用RegisterHandlerClass路线,那么它究竟能帮助我什么?我怎样才能使这些类注册相应的处理程序类,而不必像“寄存器登记”一样拥有一个“寄存器登记表”呢? - Tavian Barnes
如果问题是Handler类没有被加载,那么我的RegisterHandlerClass想法也不会起作用。你可以相反地为每个Handler类创建一个资源文件,并将它们都放在同一个目录中,然后在运行时只需扫描该目录即可。 - Old Pro

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接