I wrote an annotation processor (to copy some java sources in my compiling directory). I was surprised to see that only the files specified on the javac
command line are processed by my annotation processor. I'm obviously missing something.
Here is a minimal example:
sandbox.Aproc:
(...)
@SupportedSourceVersion(SourceVersion.RELEASE_8)
public class AProc extends AbstractProcessor{
@Override
public Set<String> getSupportedAnnotationTypes() {
return Arrays.asList( Include.class ).stream().
map(C->C.getName()).
collect(Collectors.toSet())
;
}
private void copySource(final javax.lang.model.element.Element element)
{
if(element==null || element.getKind()!=ElementKind.CLASS) return;
final String thisDir = System.getProperty("user.dir");
System.err.println("##Visit " + element);
(...)
}
@Override
public boolean process(final Set<? extends TypeElement> annotations,
final RoundEnvironment roundEnv
) {
roundEnv.getElementsAnnotatedWith(Include.class).stream().
filter(E->E.getKind()==ElementKind.CLASS).
filter(E-> E.getAnnotation(Include.class) !=null).
forEach(E->{
copySource(E);
});
return true;
}
}
sandbox/Test.java This class uses Test2 so I expect this Test2 will also be visited by the processor.
package sandbox;
@Include
public class Test {
Test2 get() { return new Test2();}
}
sandbox/Test2.java
package sandbox;
@Include
public class Test2 {
}
sandbox/Include.java
(...)
package sandbox;
@Retention(RUNTIME)
@Target({ ElementType.TYPE })
public @interface Include
{
}
The annotation processor is packaged in a jar with sandbox.AProc
in TMP/META-INF/services/javax.annotation.processing.Processor
When I compile with both Test.java and Test2.java they both appear in the processor logs.
$ javac -cp .:annot.jar -d TMP sandbox/Test.java sandbox/Test2.java
##Visit sandbox.Test
##Visit sandbox.Test2
but if I only compile sandbox/Test.java, Test2 is compiled but ignored by the processor.
$ javac -cp .:annot.jar -d TMP sandbox/Test.java
##Visit sandbox.Test
warning: Implicitly compiled files were not subject to annotation processing.
Use -proc:none to disable annotation processing or -implicit to specify a policy for implicit compilation.
1 warning
(I'm not sure about the warning, using -implicit:class hide the problem).
How can I tell the processor to visit all the classes without specifying them on the javac command line ?