United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
Bug ID: 7159016 Static import of member in processor-generated class fails in JDK 7
7159016 : Static import of member in processor-generated class fails in JDK 7

Details
Type:
Bug
Submit Date:
2012-04-04
Status:
Closed
Updated Date:
2012-07-11
Project Name:
JDK
Resolved Date:
2012-07-11
Component:
tools
OS:
linux,generic
Sub-Component:
javac
CPU:
x86,generic
Priority:
P3
Resolution:
Fixed
Affected Versions:
7,7u1
Fixed Versions:
8

Related Reports
Backport:
Duplicate:
Duplicate:

Sub Tasks

Description
Compile and run the following test case:

---%<---
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
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.Diagnostic;
import javax.tools.JavaCompiler;
import javax.tools.ToolProvider;
public class Demo {
    public static void main(String[] args) throws Exception {
        File src = new File(System.getProperty("java.io.tmpdir"), "C.java");
        Writer w = new FileWriter(src);
        try {
            w.write("import static p.Generated.m;\nclass C {{m();}}\n");
            w.flush();
        } finally {
            w.close();
        }
        JavaCompiler jc = ToolProvider.getSystemJavaCompiler();
        JavaCompiler.CompilationTask task = jc.getTask(null, null, null, null, null, jc.getStandardFileManager(null, null, null).getJavaFileObjects(src));
        task.setProcessors(Collections.singleton(new Proc()));
        System.out.println("success? " + task.call());
    }
    @SupportedAnnotationTypes("*")
    @SupportedSourceVersion(SourceVersion.RELEASE_6)
    private static class Proc extends AbstractProcessor {
        int written;
        @Override public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
            if (roundEnv.processingOver() || written++ > 0) {
                return false;
            }
            processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE, "writing Generated.java");
            try {
                Writer w = processingEnv.getFiler().createSourceFile("p.Generated").openWriter();
                try {
                    w.write("package p; public class Generated {public static void m() {}}");
                } finally {
                    w.close();
                }
            } catch (IOException x) {
                processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, x.toString());
            }
            return true;
        }
    }
}
---%<---

Output under JDK 6 is noisy but compilation succeeds:

---%<---
java version "1.6.0_31"
Java(TM) SE Runtime Environment (build 1.6.0_31-b04)
Java HotSpot(TM) Server VM (build 20.6-b01, mixed mode)

/tmp/C.java:1: package p does not exist
import static p.Generated.m;
               ^
/tmp/C.java:1: static import only from classes and interfaces
import static p.Generated.m;
^
Note: writing Generated.java
success? true
---%<---

But using JDK 7 it fails:

---%<---
java version "1.7.0_03"
Java(TM) SE Runtime Environment (build 1.7.0_03-b04)
Java HotSpot(TM) Server VM (build 22.1-b02, mixed mode)

/tmp/C.java:1: error: package p does not exist
import static p.Generated.m;
               ^
/tmp/C.java:1: error: static import only from classes and interfaces
import static p.Generated.m;
^
/tmp/C.java:2: error: cannot find symbol
class C {{m();}}
          ^
  symbol:   method m()
  location: class C
3 errors
success? false
---%<---

(Confirmed bug also in 7u1, 7u2, and 7u4b18.)

                                    

Comments
SUGGESTED FIX

http://hg.openjdk.java.net/jdk8/tl/langtools/rev/844478076c25
                                     
2012-05-31
WORK AROUND

Use a wildcard import:

            w.write("import static p.Generated.*;\nclass C {{m();}}\n");
                                               ^
                                     
2012-04-04
PUBLIC COMMENTS

Worked around in NetBeans sources: http://hg.netbeans.org/core-main/rev/df13bdc30186
                                     
2012-04-04
EVALUATION

Perhaps caused by work done in JDK 7 to avoid printing error messages relating to missing types until processors have had a chance to generate them and trigger a new compilation round. If I recall correctly that fix had a whitelist of error messages such as "cannot find symbol" or "package ... does not exist" which might be resolved in a subsequent round; perhaps "static import only from classes and interfaces" needs to be added to the list, or perhaps this error should not be emitted at all unless the identifier is known to exist but is a package rather than a type?
                                     
2012-04-04
WORK AROUND

Or avoid the import entirely:

            w.write("class C {{p.Generated.m();}}\n");
                               ^^^^^^^^^^^^

or import only the type:

            w.write("import p.Generated;\nclass C {{Generated.m();}}\n");
                                       ^            ^^^^^^^^^^
                                     
2012-04-04
EVALUATION

Yes, the diag for "package does not exist" should be marked with DiagnosticFlag.RECOVERABLE
                                     
2012-04-04



Hardware and Software, Engineered to Work Together