JDK-7026845 : Regression since JDK7b130: VariableElement.getConstantValue() leads to java.lang.AssertionError
  • Type: Bug
  • Component: core-libs
  • Sub-Component: javax.annotation.processing
  • Affected Version: 7
  • Priority: P2
  • Status: Closed
  • Resolution: Not an Issue
  • OS: generic
  • CPU: generic
  • Submitted: 2011-03-11
  • Updated: 2011-03-15
  • Resolved: 2011-03-15
Related Reports
Relates :  
Relates :  
Description
Since JDK7b130.
If the following annotation processor:

----------------------------------------------------------------------
@SupportedSourceVersion(SourceVersion.RELEASE_7)
@SupportedAnnotationTypes("*")
public class Processor extends AbstractProcessor {

    private Set<? extends Element> rootElements;

    @Override
    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
        Messager m = processingEnv.getMessager();
        if (roundEnv.processingOver()) {
            Set<? extends Element> elements = rootElements;
            for (Element element : elements) {
                m.printMessage(Kind.NOTE, "- Root element name: " + element.getSimpleName());

                for (Element e : ElementFilter.fieldsIn(element.getEnclosedElements())) {
                    m.printMessage(Kind.NOTE, "-  Field name: " + e.getSimpleName());
(1)                 Object o = ((VariableElement)e).getConstantValue();
(2)                 m.printMessage(Kind.NOTE, "-  Value: " + o);
                }
            }
        } else {
            rootElements = roundEnv.getRootElements();
        }
        return true;
    }
----------------------------------------------------------------------

is applied to the following source:

----------------------------------------------------------------------
public interface ValidInterface {
    int integerField = 1;
}
----------------------------------------------------------------------

Then the output is:

----------------------------------------------------------------------
java.lang.IllegalStateException                                                                                                                              
        at com.sun.tools.javac.util.Context.checkState(Context.java:205)                                                                                     
        at com.sun.tools.javac.util.Context.get(Context.java:141)
        at com.sun.tools.javac.code.Symtab.instance(Symtab.java:57)
        at com.sun.tools.javac.code.Lint$AugmentVisitor.initSyms(Lint.java:298)
        at com.sun.tools.javac.code.Lint$AugmentVisitor.augment(Lint.java:287)
        at com.sun.tools.javac.code.Lint.augment(Lint.java:82)
        at com.sun.tools.javac.comp.Attr.attribLazyConstantValue(Attr.java:597)
        at com.sun.tools.javac.code.Symbol$VarSymbol$1.call(Symbol.java:973)
        at com.sun.tools.javac.code.Symbol$VarSymbol.getConstValue(Symbol.java:1005)
        at com.sun.tools.javac.code.Symbol$VarSymbol.getConstantValue(Symbol.java:964)
        at test.Processor.process(Processor.java:44)
        at com.sun.tools.javac.processing.JavacProcessingEnvironment.callProcessor(JavacProcessingEnvironment.java:786)
        at com.sun.tools.javac.processing.JavacProcessingEnvironment.access$200(JavacProcessingEnvironment.java:94)
        at com.sun.tools.javac.processing.JavacProcessingEnvironment$DiscoveredProcessors$ProcessorStateIterator.runContributingProcs(JavacProcessingEnvironment.java:637)
        at com.sun.tools.javac.processing.JavacProcessingEnvironment$Round.run(JavacProcessingEnvironment.java:1010)
        at com.sun.tools.javac.processing.JavacProcessingEnvironment.doProcessing(JavacProcessingEnvironment.java:1157)
        at com.sun.tools.javac.main.JavaCompiler.processAnnotations(JavaCompiler.java:1085)
        at com.sun.tools.javac.main.JavaCompiler.compile(JavaCompiler.java:801)
        at com.sun.tools.javac.main.Main.compile(Main.java:411)
        at com.sun.tools.javac.main.Main.compile(Main.java:329)
        at com.sun.tools.javac.main.Main.compile(Main.java:320)
        at com.sun.tools.javac.Main.compile(Main.java:76)
        at com.sun.tools.javac.Main.main(Main.java:61)


An annotation processor threw an uncaught exception.
Consult the following stack trace for details.
java.lang.AssertionError: java.lang.IllegalStateException
        at com.sun.tools.javac.code.Symbol$VarSymbol.getConstValue(Symbol.java:1008)
        at com.sun.tools.javac.code.Symbol$VarSymbol.getConstantValue(Symbol.java:964)
        at test.Processor.process(Processor.java:44)
        at com.sun.tools.javac.processing.JavacProcessingEnvironment.callProcessor(JavacProcessingEnvironment.java:786)
        at com.sun.tools.javac.processing.JavacProcessingEnvironment.access$200(JavacProcessingEnvironment.java:94)
        at com.sun.tools.javac.processing.JavacProcessingEnvironment$DiscoveredProcessors$ProcessorStateIterator.runContributingProcs(JavacProcessingEnvironment.java:637)
        at com.sun.tools.javac.processing.JavacProcessingEnvironment$Round.run(JavacProcessingEnvironment.java:1010)
        at com.sun.tools.javac.processing.JavacProcessingEnvironment.doProcessing(JavacProcessingEnvironment.java:1157)
        at com.sun.tools.javac.main.JavaCompiler.processAnnotations(JavaCompiler.java:1085)
        at com.sun.tools.javac.main.JavaCompiler.compile(JavaCompiler.java:801)
        at com.sun.tools.javac.main.Main.compile(Main.java:411)
        at com.sun.tools.javac.main.Main.compile(Main.java:329)
        at com.sun.tools.javac.main.Main.compile(Main.java:320)
        at com.sun.tools.javac.Main.compile(Main.java:76)
        at com.sun.tools.javac.Main.main(Main.java:61)
Caused by: java.lang.IllegalStateException
        at com.sun.tools.javac.util.Context.checkState(Context.java:205)
        at com.sun.tools.javac.util.Context.get(Context.java:141)
        at com.sun.tools.javac.code.Symtab.instance(Symtab.java:57)
        at com.sun.tools.javac.code.Lint$AugmentVisitor.initSyms(Lint.java:298)
        at com.sun.tools.javac.code.Lint$AugmentVisitor.augment(Lint.java:287)
        at com.sun.tools.javac.code.Lint.augment(Lint.java:82)
        at com.sun.tools.javac.comp.Attr.attribLazyConstantValue(Attr.java:597)
        at com.sun.tools.javac.code.Symbol$VarSymbol$1.call(Symbol.java:973)
        at com.sun.tools.javac.code.Symbol$VarSymbol.getConstValue(Symbol.java:1005)
        ... 14 more

----------------------------------------------------------------------

If one comments lines (1),(2) then the output is:

----------------------------------------------------------------------
Note: - Root element name: ValidInterface
Note: -  Field name: integerField
----------------------------------------------------------------------

Comments
WORK AROUND The root cause is that the rootElements are being cached from the first round and used in the last round. Instead, you should only be using elements from the same round.
11-03-2011

EVALUATION This is almost certainly because of the following changeset: Changeset: 899f7c3d9426 Author: mcimadamore Date: 2011-02-03 09:35 +0000 URL: http://hg.openjdk.java.net/jdk7/tl/langtools/rev/899f7c3d9426 6594914: @SuppressWarnings("deprecation") does not not work for the type of a variable Summary: Lint warnings generated during MemberEnter might ignore @SuppressWarnings annotations Reviewed-by: jjg Previously, javac did not check for @SuppressWarnings on VarSymbols. Now it does, as it should. But, a side effect is that more processing goes on when getConstantValue is called. In particular, notice the references to Lint in the stacktrace -- that is the SuppressWarnings mechanism at work. The root cause is that the rootElements are being cached from the first round and used in the last round. Instead, you should be using elements from the same round.
11-03-2011

EVALUATION The example code is saving the rootElements from one round and using them in a later round. This is not supported. You should only use the elements available in each round. Will continue to investigate why the regression has occurred.
11-03-2011