2014-11-25 24 views
2

我有一个注释处理器,用于查找包含特定注释的文件。处理器的输出是一个文件,引用每个这样的注释文件。当只有一个子集被编译时,注释处理器需要处理所有文件,但是如何?

例如,如果类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,YZ参考文献的正确供应商文件。但是,如果只是X发生更改,则不会生成新的提供程序文件。这允许增量编译,但是在必要的时候记住要做clean

我不确定这里是否有一个通用的解决方案,但我总是问。我想我真正想要的是注释处理器在compile阶段之后通过target/classes目录运行。我可能需要为此写一个maven插件。

回答

1

有一个bug in maven-compiler-plugin version 3.1. that causes incremental builds to fail。无论如何,目前最新的版本是3.2。

这很糟糕。

只是因为它打破了你当前的处理器。正如你自己所指出的那样,这并不是所有时间重建一切的最佳解决方案。更好的方法是支持增量构建。这将使构建更快,并且您的处理器与更多编译器,IDE和构建工具兼容。你可能需要一种新的方式来处理你的注释类。

这是一个想法,你可以去支持增量构建。

您不是像FooFiles那样收集所有类在一个地方,而是生成一个资源文件,该文件将列出您的所有类,然后添加您在增量构建中遇到的每个带注释的类。每当需要使用FooFiles时,您都可以从该资源文件读取类。您还需要删除已删除或未注释的列表中的类。

如果你的处理器比较复杂,它不会那么简单,但我的一般方法仍然可以工作。您也可以为每个注释类生成一个类,如果属性文件不够,它会在某处动态注册它自己。

+0

我喜欢用它们中的类名列表生成资源文件的想法。当带有注解的类被编译时,它确保它的名字在该文件中。提供者类然后加载资源文件并创建那里列出的类的实例。唯一的问题是它不会处理从资源文件中删除类名称。如果注释从文件中移除,注释处理器将看不到注释,并且它不会自行移除。除非有办法知道哪些类已编译但未由注释处理器处理... – 2014-11-27 05:15:24

+1

我认为,如果处理器支持所有注释,即使注释被移除时它也会始终使用,它可以工作。在处理器的每次执行中,您都应该能够使用反射/镜像API,并查看列表中的类和它们的注释是否仍然存在。 tbh我从来没有尝试过这个。另外我不确定当你删除一个类时,编译/处理甚至会被所有的IDE调用。如果没有,我想你需要在运行时检查列出的类是否真的存在。 – Kapep 2014-11-28 19:28:50

+1

这可能会起作用,所以我会将其标记为答案。不过,我认为绕过注释处理可能是更好的解决方案。我编写了一个quick-n-dirty maven插件,用于处理targets/classes目录中的类文件,使用注释查找类,并将java文件生成到targets/generated-test-sources。这个插件在generate-test-sources阶段运行。似乎有效且正确地工作,但我必须将注释的保留策略从COMPILE更改为RUNTIME。 – 2014-11-30 23:28:18