JDK-8145738 : ClassCastException in javac from Elements#getTypeElement
  • Type: Bug
  • Component: tools
  • Sub-Component: javac
  • Affected Version: 7u80
  • Priority: P4
  • Status: Closed
  • Resolution: Duplicate
  • OS: os_x
  • CPU: x86
  • Submitted: 2015-12-10
  • Updated: 2016-05-25
  • Resolved: 2015-12-18
Related Reports
Duplicate :  
Description
FULL PRODUCT VERSION :
java version "1.7.0_80"
Java(TM) SE Runtime Environment (build 1.7.0_80-b15)
Java HotSpot(TM) 64-Bit Server VM (build 24.80-b11, mixed mode)

ADDITIONAL OS VERSION INFORMATION :
OS X 10.10.5
Darwin Kernel Version 14.5.0

A DESCRIPTION OF THE PROBLEM :
Appears to be fixed in Java 8. But I have a case where an annotation processor is calling Elements#getTypeElement for a type that does not exist. The method is specified to return null in this case. But instead, it throws an exception:

java.lang.ClassCastException: com.sun.tools.javac.comp.Resolve$SymbolNotFoundError cannot be cast to com.sun.tools.javac.code.Symbol$ClassSymbol
	at com.sun.tools.javac.comp.Attr$IdentAttributer.visitMemberSelect(Attr.java:313)
...

I've included a repro trivial case in "Steps to Reproduce" below.


STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
See source code in four files total under "Source code for an executable test case" section.

Compile the annotation and the processor:
> javac Repro.java ReproProcessor.java

Compile the test class and observe exception:
> javac Basic.java


EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The method should return null instead of throwing.
ACTUAL -
Exception is thrown:

java.lang.ClassCastException: com.sun.tools.javac.comp.Resolve$SymbolNotFoundError cannot be cast to com.sun.tools.javac.code.Symbol$ClassSymbol
	at com.sun.tools.javac.comp.Attr$IdentAttributer.visitMemberSelect(Attr.java:313)
...

ERROR MESSAGES/STACK TRACES THAT OCCUR :
java.lang.ClassCastException: com.sun.tools.javac.comp.Resolve$SymbolNotFoundError cannot be cast to com.sun.tools.javac.code.Symbol$ClassSymbol
	at com.sun.tools.javac.comp.Attr$IdentAttributer.visitMemberSelect(Attr.java:313)
	at com.sun.tools.javac.comp.Attr$IdentAttributer.visitMemberSelect(Attr.java:302)
	at com.sun.tools.javac.tree.JCTree$JCFieldAccess.accept(JCTree.java:1683)
	at com.sun.tools.javac.comp.Attr.attribIdent(Attr.java:298)
	at com.sun.tools.javac.main.JavaCompiler.resolveIdent(JavaCompiler.java:672)
	at com.sun.tools.javac.model.JavacElements.nameToSymbol(JavacElements.java:162)
	at com.sun.tools.javac.model.JavacElements.getTypeElement(JavacElements.java:144)
	at com.sun.tools.javac.model.JavacElements.getTypeElement(JavacElements.java:61)
	at ReproProcessor.process(ReproProcessor.java:16)
	at com.sun.tools.javac.processing.JavacProcessingEnvironment.callProcessor(JavacProcessingEnvironment.java:793)
	at com.sun.tools.javac.processing.JavacProcessingEnvironment.discoverAndRunProcs(JavacProcessingEnvironment.java:722)
	at com.sun.tools.javac.processing.JavacProcessingEnvironment.access$1700(JavacProcessingEnvironment.java:97)
	at com.sun.tools.javac.processing.JavacProcessingEnvironment$Round.run(JavacProcessingEnvironment.java:1029)
	at com.sun.tools.javac.processing.JavacProcessingEnvironment.doProcessing(JavacProcessingEnvironment.java:1163)
	at com.sun.tools.javac.main.JavaCompiler.processAnnotations(JavaCompiler.java:1108)
	at com.sun.tools.javac.main.JavaCompiler.compile(JavaCompiler.java:824)
	at com.sun.tools.javac.main.Main.compile(Main.java:439)
	at com.sun.tools.javac.main.Main.compile(Main.java:353)
	at com.sun.tools.javac.main.Main.compile(Main.java:342)
	at com.sun.tools.javac.main.Main.compile(Main.java:333)
	at com.sun.tools.javac.Main.compile(Main.java:76)
	at com.sun.tools.javac.Main.main(Main.java:61)

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
Four files in total:

META-INF/services/javax.annotation.processing.Processor:
---------------------------------------
ReproProcessor
---------------------------------------


Repro.java:
---------------------------------------
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

@Retention(RetentionPolicy.RUNTIME)
public @interface Repro {
}
---------------------------------------


ReproProcessor.java:
---------------------------------------
import java.util.Set;
import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.RoundEnvironment;
import javax.annotation.processing.SupportedAnnotationTypes;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.TypeElement;

@SupportedAnnotationTypes("Repro")
public class ReproProcessor extends AbstractProcessor {

  @Override public SourceVersion getSupportedSourceVersion() {
    return SourceVersion.latestSupported();
  }

  @Override public boolean process(Set<? extends TypeElement> types, RoundEnvironment env) {
    processingEnv.getElementUtils().getTypeElement("Basic.Foo.Bar");
    return false;
  }  
}
---------------------------------------


Basic.java
---------------------------------------
class Basic {
  static class A { A() { } }
  static class Foo$Bar {
    Foo$Bar() { }
    static class Baz { Baz() { } }
  }
  @Repro
  static class AModule { }
}
---------------------------------------

---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
Update annotation processor to catch exceptions thrown by Elements#getTypeElement and treat as if null return value.


Comments
This issue is duplicate of JDK-7071377
18-12-2015

This issue is not reproducible tested with all the versions of Java.
18-12-2015