我有一个注释处理器,用于查找包含特定注释的文件。处理器的输出是一个文件,引用每个这样的注释文件。当只有一个子集被编译时,注释处理器需要处理所有文件,但是如何?
例如,如果类X,ÿ,和Ž包含注释@foo,则@foo处理器将产生像一个文件:
class FooFiles {
Class[] getFooClasses() {
return new Class[]{X.class,Y.class,Z.class};
}
}
这如果我执行mvn clean compile
,则工作正常,因为所有类都被编译并传递给注释处理器。
但如果类是最新的,而我只修改一个(说X类),那么mvn compile
将执行增量构建,并且因为只有X类被编译,那么只有X类被传递到标注处理程序,生成的文件是:
class FooFiles {
Class[] getFooClasses() {
return new Class[]{X.class};
}
}
这是不好的。
我正在使用maven与maven-compiler-plugin
版本2.5.1,这似乎做增量编译。
如果我将maven-compiler-plugin
更新为版本3.1,则任何一个文件的更改都会导致编译所有文件,并且不会出现此问题(尽管只有一个文件发生更改时编译所有文件可能不是此处的解决方案,其他开发人员会因为一个文件更改而需要从头开始重新编译带有10K +文件的模块时才会投诉)。我曾尝试在插件的配置中将useIncrementalCompilation
选项设置为true
,但似乎无论如何重新编译所有文件。
我修改了我的注释处理器,以便它不覆盖任何现有的生成文件。这意味着在clean
之后,生成包含X,Y和Z参考文献的正确供应商文件。但是,如果只是X发生更改,则不会生成新的提供程序文件。这允许增量编译,但是在必要的时候记住要做clean
。
我不确定这里是否有一个通用的解决方案,但我总是问。我想我真正想要的是注释处理器在compile
阶段之后通过target/classes
目录运行。我可能需要为此写一个maven插件。
我喜欢用它们中的类名列表生成资源文件的想法。当带有注解的类被编译时,它确保它的名字在该文件中。提供者类然后加载资源文件并创建那里列出的类的实例。唯一的问题是它不会处理从资源文件中删除类名称。如果注释从文件中移除,注释处理器将看不到注释,并且它不会自行移除。除非有办法知道哪些类已编译但未由注释处理器处理... – 2014-11-27 05:15:24
我认为,如果处理器支持所有注释,即使注释被移除时它也会始终使用,它可以工作。在处理器的每次执行中,您都应该能够使用反射/镜像API,并查看列表中的类和它们的注释是否仍然存在。 tbh我从来没有尝试过这个。另外我不确定当你删除一个类时,编译/处理甚至会被所有的IDE调用。如果没有,我想你需要在运行时检查列出的类是否真的存在。 – Kapep 2014-11-28 19:28:50
这可能会起作用,所以我会将其标记为答案。不过,我认为绕过注释处理可能是更好的解决方案。我编写了一个quick-n-dirty maven插件,用于处理targets/classes目录中的类文件,使用注释查找类,并将java文件生成到targets/generated-test-sources。这个插件在generate-test-sources阶段运行。似乎有效且正确地工作,但我必须将注释的保留策略从COMPILE更改为RUNTIME。 – 2014-11-30 23:28:18