Maven 当只编译一个子集时,注释处理器需要处理所有文件,但如何处理?

Maven 当只编译一个子集时,注释处理器需要处理所有文件,但如何处理?,maven,annotations,Maven,Annotations,我有一个注释处理器,用于查找包含特定注释的文件。处理器的输出是一个文件,它引用每个这样的带注释的文件 例如,如果类X、Y和Z包含注释@Foo,则@Foo处理器将生成一个类似以下内容的文件: class FooFiles { Class[] getFooClasses() { return new Class[]{X.class,Y.class,Z.class}; } } 如果我执行mvn clean compile,这很好,因为所有类都被编译并传递给注释处理器 但是如果类是

我有一个注释处理器,用于查找包含特定注释的文件。处理器的输出是一个文件,它引用每个这样的带注释的文件

例如,如果类X、Y和Z包含注释@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编译器插件一起使用
Version2.5.1,它似乎可以进行增量编译

如果我将
maven编译器插件
更新为3.1版,那么一个文件中的任何更改都会导致编译所有文件,并且不会出现此问题(虽然在只有一个文件发生更改时编译所有文件可能不是这里的解决方案,但是当一个包含10K+文件的模块由于一个文件更改而需要从头开始重新编译时,其他开发人员会抱怨)。我确实尝试过在插件的配置中将
useIncrementalComplation
选项设置为
true
,但它似乎会重新编译所有文件

我修改了注释处理器,使其不会覆盖任何现有生成的文件。这意味着在
清理
后,将生成包含X、Y和Z引用的正确提供程序文件。但是,例如,如果仅X发生更改,则不会生成新的提供程序文件。这允许增量编译,但在记住在必要时进行清洁

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

有一个。目前最新版本是3.2

这很糟糕

只是因为它破坏了您当前的处理器。正如您自己所指出的,它不是始终重建所有内容的最佳解决方案。更好的方法是支持增量生成。这将使生成更快,并且使您的处理器与更多编译器、IDE和生成工具兼容。您可能需要一种新的方法来处理带注释的不过是上课

下面是一个如何支持增量构建的想法

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


如果你的处理器更复杂,那就没那么容易了,但我认为一般的方法应该仍然有效。如果属性文件不够,你还可以为每个带注释的类生成一个类,在某个地方动态注册它自己。

我喜欢生成一个包含类名列表的资源文件的想法在编译注释时,它会确保其名称在该文件中。然后,提供程序类加载资源文件并创建其中列出的类的实例。唯一的问题是它无法处理从资源文件中删除类名的问题。如果从文件中删除注释,注释处理器将看不到它,并且不会删除自身。除非有办法知道哪些类是编译的,而不是由注释处理器处理的……我认为如果处理器支持所有注释,它可以工作,这样即使注释被删除,它也会一直被使用。在处理器的每次执行中,您应该能够使用反射/镜像api并ee如果列表中的类及其注释仍然存在。tbh我从未尝试过。此外,我不确定当您刚刚删除一个类时,是否所有IDE都会调用编译/处理。如果不是,我想您需要在运行时检查列出的类是否真的存在。这可能会起作用,因此我将其标记为答案。如何我曾经认为绕过注释处理可能是更好的解决方案。我编写了一个quick-n-dirty maven插件,该插件处理targets/classes目录中的类文件,查找带有注释的类,并将java文件生成到目标/生成的测试源中。该插件在生成测试源阶段运行。似乎有效且正确地工作,但我必须将注释的保留策略从编译更改为运行时。我修改了maven类处理插件以查找自上次运行以来已更改的类文件,而不是加载目录中的所有类文件并依次处理每个类文件。因此,现在有了一个资源文件存储ng类文件名及其修改时间,并将其与目录中的文件进行比较以生成更改集。然后使用更改集(带有ADD、DELETE、MODIFY info)更新另一个资源文件,该文件存储带有@Foo注释的类列表。然后使用该文件生成所需代码。现在运行速度更快。