JDK-6999068 : -Xlint warns unnecessarily about unclaimed annotations
  • Type: Bug
  • Component: tools
  • Sub-Component: javac
  • Affected Version: 6
  • Priority: P4
  • Status: Closed
  • Resolution: Won't Fix
  • OS: linux
  • CPU: x86
  • Submitted: 2010-11-10
  • Updated: 2019-03-06
  • Resolved: 2019-03-06
Related Reports
Relates :  
Description
---%<---
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.

Comments
The warning in question is not printed for annotations in java.lang and java.lang.annotation (JDK-8193214 and preceding work). As a matter of policy, keeping the other warnings. Closing as will not fix.
06-03-2019

EVALUATION Strictly speaking, the synopsis is incorrect. This is not an issue about -Xlint. It is an issue about the policies of annotation processing generating warnings. The -Xlint mechanism is being leveraged as part of the proposed solution.
10-11-2010

WORK AROUND -Xlint:-processing, after checking that this is the only warning that would be suppressed.
10-11-2010

SUGGESTED FIX # HG changeset patch # Parent 5bb96781fb58c4ebea9d640c9b251b3c19d54f82 Add [processing] prefix to all warnings printed by -Xlint:processing. diff --git a/src/share/classes/com/sun/tools/javac/processing/JavacFiler.java b/src/share/classes/com/sun/tools/javac/processing/JavacFiler.java --- a/src/share/classes/com/sun/tools/javac/processing/JavacFiler.java +++ b/src/share/classes/com/sun/tools/javac/processing/JavacFiler.java @@ -390,7 +390,7 @@ String base = name.substring(periodIndex); String extn = (isSourceFile ? ".java" : ".class"); if (base.equals(extn)) - log.warning("proc.suspicious.class.name", name, extn); + log.warning(PROCESSING, "proc.suspicious.class.name", name, extn); } } checkNameAndExistence(name, isSourceFile); @@ -403,8 +403,8 @@ fileManager.getJavaFileForOutput(loc, name, kind, null); checkFileReopening(fileObject, true); - if (lastRound) - log.warning("proc.file.create.last.round", name); + if (/* XXX lint && */lastRound) + log.warning(/* XXX PROCESSING, */"proc.file.create.last.round", name); if (isSourceFile) aggregateGeneratedSourceNames.add(name); @@ -476,7 +476,7 @@ private void checkName(String name, boolean allowUnnamedPackageInfo) throws FilerException { if (!SourceVersion.isName(name) && !isPackageInfo(name, allowUnnamedPackageInfo)) { if (lint) - log.warning("proc.illegal.file.name", name); + log.warning(PROCESSING, "proc.illegal.file.name", name); throw new FilerException("Illegal name " + name); } } @@ -503,7 +503,7 @@ if (aggregateGeneratedSourceNames.contains(typename) || aggregateGeneratedClassNames.contains(typename)) { if (lint) - log.warning("proc.type.recreate", typename); + log.warning(PROCESSING, "proc.type.recreate", typename); throw new FilerException("Attempt to recreate a file for type " + typename); } } @@ -516,7 +516,7 @@ for(FileObject veteran : fileObjectHistory) { if (fileManager.isSameFile(veteran, fileObject)) { if (lint) - log.warning("proc.file.reopening", fileObject.getName()); + log.warning(PROCESSING, "proc.file.reopening", fileObject.getName()); throw new FilerException("Attempt to reopen a file for path " + fileObject.getName()); } } @@ -542,8 +542,8 @@ } public void warnIfUnclosedFiles() { - if (!openTypeNames.isEmpty()) - log.warning("proc.unclosed.type.files", openTypeNames.toString()); + if (/* XXX lint && */!openTypeNames.isEmpty()) + log.warning(/* XXX PROCESSING, */"proc.unclosed.type.files", openTypeNames.toString()); } /** diff --git a/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java b/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java --- a/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java +++ b/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java @@ -737,7 +737,7 @@ unmatchedAnnotations.keySet().removeAll(platformAnnotations); if (unmatchedAnnotations.size() > 0) { log = Log.instance(context); - log.warning("proc.annotations.without.processors", + log.warning(PROCESSING, "proc.annotations.without.processors", unmatchedAnnotations.keySet()); } }
10-11-2010