JDK-6911972 : "cannot find symbol" errors for classes which are about to be generated by an AP
  • Type: Bug
  • Component: tools
  • Sub-Component: javac
  • Affected Version: 6
  • Priority: P4
  • Status: Closed
  • Resolution: Duplicate
  • OS: linux
  • CPU: x86
  • Submitted: 2009-12-18
  • Updated: 2010-09-30
  • Resolved: 2009-12-20
Related Reports
Duplicate :  
Description
Reproducible with JDK 6 or 7:

---%<---
$ cat ProcessorImpl.java UsesGenerated.java
import java.io.IOException;
import java.io.Writer;
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.Diagnostic.Kind;
@SupportedAnnotationTypes("*")
@SupportedSourceVersion(SourceVersion.RELEASE_7)
public class ProcessorImpl extends AbstractProcessor {
    boolean ran;
    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
        if (roundEnv.processingOver()) {
            return false;
        }
        if (ran) {
            return false;
        }
        try {
            Writer w = processingEnv.getFiler().createSourceFile("Generated").openWriter();
            w.write("class Generated {}");
            w.close();
        } catch (IOException x) {
            processingEnv.getMessager().printMessage(Kind.ERROR, x.toString());
        }
        ran = true;
        return true;
    }
}
public class UsesGenerated {
    Generated g;
}
$ javac ProcessorImpl.java
$ javac -J-showversion -processorpath . -processor ProcessorImpl UsesGenerated.java
java version "1.6.0_17"
Java(TM) SE Runtime Environment (build 1.6.0_17-b04)
Java HotSpot(TM) Client VM (build 14.3-b01, mixed mode, sharing)

UsesGenerated.java:2: cannot find symbol
symbol  : class Generated
location: class UsesGenerated
    Generated g;
    ^
$ javap -classpath . Generated UsesGenerated
Compiled from "Generated.java"
class Generated extends java.lang.Object{
    Generated();
}

Compiled from "UsesGenerated.java"
public class UsesGenerated extends java.lang.Object{
    Generated g;
    public UsesGenerated();
}
---%<---

The error output from javac makes it look like compilation failed. In fact, everything went normally and all classes have been compiled successfully. "cannot find symbol" errors may be misleading when they are produced before a source-generating annotation processor has run.

Comments
EVALUATION Yes, a long-standing limitation in the implementation. Duplicate of 6403465; closing this bug accordingly.
20-12-2009

SUGGESTED FIX If annotation processors are active, queue up any "cannot find symbol" errors encountered. If at the end of a given processing round no sources have been generated, then print these errors. Otherwise discard them before rerunning compilation with the expanded source set. (I am assuming that this is the only error which javac could generate that would be corrected by injecting a new source file. Perhaps there are obscure cases where a new source file would cause an ambiguous expression to be resolved in a different way, leading to a different kind of error, but I cannot think of any such cases and they are probably so rare as to not be worth consideration. It *is* useful to report other errors before an AP runs, i.e. those which would have been erroneous even with the generated sources.)
18-12-2009

PUBLIC COMMENTS Impediment to using annotation processors to generate source code, e.g. in https://netbeans.org/bugzilla/show_bug.cgi?id=178426 since true errors in build logs can be obscured by these phantom errors. The NetBeans IDE's Ant integration also automatically halts scrolling of the output window the first time a javac error message is encountered, which is normally desirable as you are most likely interested in starting with the first error, rather than seeing the end of the build. But this algorithm is broken by this javac bug, since even successful builds will display an error (and builds which fail much later for unrelated reasons will show the wrong error).
18-12-2009

WORK AROUND None known, except perhaps to use JSR 199 to wrap javac in a custom tool that modifies its output in the suggested way.
18-12-2009