---%<---
import java.io.File;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.Collections;
import java.util.Set;
import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.RoundEnvironment;
import javax.annotation.processing.SupportedAnnotationTypes;
import javax.annotation.processing.SupportedSourceVersion;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.TypeElement;
import javax.tools.JavaCompiler;
import javax.tools.JavaCompiler.CompilationTask;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;
public class JavacBug {
private JavacBug() {}
public @interface A {}
@SupportedAnnotationTypes("JavacBug.A")
@SupportedSourceVersion(SourceVersion.RELEASE_6)
private static class P extends AbstractProcessor {
public @Override boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
return true;
}
}
public static void main(String[] args) throws Exception {
JavaCompiler c = ToolProvider.getSystemJavaCompiler();
StandardJavaFileManager mgr = c.getStandardFileManager(null, null, null);
File src = File.createTempFile("Demo", ".java");
src.deleteOnExit();
PrintWriter pw = new PrintWriter(src);
pw.println("@JavacBug.A");
pw.println("@javax.annotation.Resource");
pw.println("class " + src.getName().replaceFirst("[.]java$", "") + " {}");
pw.close();
CompilationTask t = c.getTask(null, mgr, null, Arrays.asList("-Xlint"/*, "-Xlint:-processing"*/), null, mgr.getJavaFileObjects(src));
t.setProcessors(Collections.singleton(new P()));
System.out.println(t.call());
}
}
---%<---
Run under JDK 6u22 with tools.jar on the classpath, this prints:
---%<---
warning: No processor claimed any of these annotations: [javax.annotation.Resource]
true
---%<---
Discussion:
NetBeans modules often have API modules on their processor path which include processors registered in the normal way to handle certain kinds of annotations (with source retention). New modules are created with javac options set to -Xlint (to get useful warnings) and -Xlint:-serial (since this warning is printed far too often, just for e.g. making Swing components which no one in their right mind would serialize).
But now if any class in the module uses an annotation which does not happen to have a processor - perfectly normal, e.g. for FindBugs, or a variety of runtime-retention annotations, even @SupportedAnnotationTypes from another processor! - javac prints this warning. Recently I met with a potential customer of the NetBeans Platform who claimed that annotation processing did not work during his testing. Pressed for details, he revealed that in fact the compilation exited normally but this warning was printed - and he interpreted a warning during output as meaning that he had done something wrong, or that the build infrastructure was not complete. Of course nothing was wrong at all except for the warning.
From grepping langtools sources it turns out that -Xlint:-processing makes the warning go away. I would not have guessed that without sources since, unlike other -Xlint suboptions, there is no " [processing]" prefix to the warning message. It seems this is fixed in current langtools trunk for some cases but not this one (see patch).
But I would rather this particular warning just not be printed at all. -Xlint:-processing looks like it would disable a bunch of other warnings, some of which may correspond to real problems, whereas proc.annotations.without.processors does not generally correspond to any actual mistake.