I have an annotation processor that looks for files that contain a certain annotation. The output of the processor is a single file, that references each such annotated file.
For example, if classes X, Y, and Z contain the annotation @Foo, then the @Foo processor will generate a file like:
class FooFiles {
Class[] getFooClasses() {
return new Class[]{X.class,Y.class,Z.class};
}
}
This works fine if I do a mvn clean compile
, since all classes are compiled and passed to the annotation processor.
But if the classes are up to date, and I modify just one (say the X class), then a mvn compile
will perform an incremental build, and since only X class is compiled, then only the X class gets passed to the annotation processor, and the generated file is:
class FooFiles {
Class[] getFooClasses() {
return new Class[]{X.class};
}
}
This is bad.
I'm using maven with maven-compiler-plugin
version 2.5.1, which seems to do incremental compilation.
If I update the maven-compiler-plugin
to version 3.1, then any change in one file results in compilation of all files, and this problem does not occur (although compiling all files when only one file has changed may not be the solution here, other developers will complain when a module with 10K+ files needs to recompiled from scratch because of one file change). I did try setting the useIncrementalCompilation
option to true
in the plugin's configuration, but it seems to recompile all files regardless.
I modified my annotation processor so that it does not overwrite any existing generated file. This means that after a clean
then the correct provider file is generated containing X,Y, and Z references. But if just X changes, for example, then a new provider file is not generated. This allows incremental compilation, but at the expense of remembering to do a clean
where necessary.
I'm not sure if there's a general solution here, but I'm asking anyway. I guess what I really want is for the annotation processor to run over the target/classes
directory after the compile
phase. I might need to write a maven plugin for that, perhaps.