JDK-7071377 : Exception when javac -processor is given a class name with invalid postfix
  • Type: Bug
  • Component: tools
  • Sub-Component: javac
  • Affected Version: 7
  • Priority: P3
  • Status: Closed
  • Resolution: Fixed
  • OS: linux_ubuntu
  • CPU: x86
  • Submitted: 2011-07-26
  • Updated: 2016-05-25
  • Resolved: 2013-08-19
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 8
8 b105Fixed
Related Reports
Duplicate :  
Description
FULL PRODUCT VERSION :
1.7.0_147 and 1.6.0_22

A DESCRIPTION OF THE PROBLEM :
Calling javac with an annotation processor and a class name with an invalid postfix raises an exception.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Create an empty directory and put the source code from the "Source code for an executable test case" box into it.
(Alternatively, you could also use
com.sun.tools.javac.processing.PrintingProcessor, but you'll need some
dummy file in your current directory anyway.)
Call

javac EmptyProcessor.java

which should succeed.


Call

javac -processor EmptyProcessor EmptyProcessor.java

You should see the output:

Empty Processor run!
Empty Processor run!


If you pass an invalid file name, you get the expected error message:

javac -processor EmptyProcessor Blub.ja
error: Could not find class file for 'Blub.ja'.
1 error


Now assume the programmer made a simple typo and ran

javac -processor EmptyProcessor EmptyProcessor.javaxxx

I now get an exception from javac.
I tried this with 1.6.0_22 and build 147 of 1.7.
Find the stack traces in the "Actual Result" box.

I only get the exception when the base filename is EmptyProcessor,
i.e. a class name that exists in the current directory.
I get an even longer stack trace when the file name contains two dots,
e.g. EmptyProcessor.x.y.

It looks like name resolution is a bit too lenient when annotation
processing is happening.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
A meaningful error message about the invalid argument.
ACTUAL -
With a single dot (EmptyProcessor.javaxxx) I get the messages:

An exception has occurred in the compiler (1.6.0_22). Please file a
bug at the Java Developer Connection
(http://java.sun.com/webapps/bugreport)  after checking the Bug Parade
for duplicates. Include your program and the following diagnostic in
your report.  Thank you.
java.lang.AssertionError
       at com.sun.tools.javac.main.JavaCompiler.processAnnotations(JavaCompiler.java:968)
       at com.sun.tools.javac.main.JavaCompiler.compile(JavaCompiler.java:727)
       at com.sun.tools.javac.main.Main.compile(Main.java:353)
       at com.sun.tools.javac.main.Main.compile(Main.java:279)
       at com.sun.tools.javac.main.Main.compile(Main.java:270)
       at com.sun.tools.javac.Main.compile(Main.java:69)
       at com.sun.tools.javac.Main.main(Main.java:54)

An exception has occurred in the compiler (1.7.0). Please file a bug
at the Java Developer Connection
(http://java.sun.com/webapps/bugreport)  after checking the Bug Parade
for duplicates. Include your program and the following diagnostic in
your report.  Thank you.
java.lang.AssertionError
       at com.sun.tools.javac.util.Assert.error(Assert.java:126)
       at com.sun.tools.javac.util.Assert.check(Assert.java:45)
       at com.sun.tools.javac.main.JavaCompiler.processAnnotations(JavaCompiler.java:1090)
       at com.sun.tools.javac.main.JavaCompiler.compile(JavaCompiler.java:824)
       at com.sun.tools.javac.main.Main.compile(Main.java:417)
       at com.sun.tools.javac.main.Main.compile(Main.java:331)
       at com.sun.tools.javac.main.Main.compile(Main.java:322)
       at com.sun.tools.javac.Main.compile(Main.java:76)
       at com.sun.tools.javac.Main.main(Main.java:61)


With two dots (EmptyProcessor.x.y) I get the message:

An exception has occurred in the compiler (1.7.0). Please file a bug
at the Java Developer Connection
(http://java.sun.com/webapps/bugreport)  after checking the Bug Parade
for duplicates. Include your program and the following diagnostic in
your report.  Thank you.
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.main.JavaCompiler.resolveBinaryNameOrIdent(JavaCompiler.java:650)
       at com.sun.tools.javac.main.JavaCompiler.processAnnotations(JavaCompiler.java:1074)
       at com.sun.tools.javac.main.JavaCompiler.compile(JavaCompiler.java:824)
       at com.sun.tools.javac.main.Main.compile(Main.java:417)
       at com.sun.tools.javac.main.Main.compile(Main.java:331)
       at com.sun.tools.javac.main.Main.compile(Main.java:322)
       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 ----------
import java.util.Set;
import javax.annotation.processing.*;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.TypeElement;

@SupportedAnnotationTypes("*")
public class EmptyProcessor extends AbstractProcessor {
    @Override
    public boolean process(Set<? extends TypeElement> annotations,
            RoundEnvironment roundEnv) {
        System.out.println("Empty Processor run!");
        return false;
    }

    @Override
    public SourceVersion getSupportedSourceVersion() {
        return SourceVersion.latest();
    }
}
---------- END SOURCE ----------

Comments
The logic has assumed that " EmptyProcessor" in " EmptyProcessor.x.y" is a package name and continues on, till it ties itself up in a pretzel. I think there must be some sort of a check to very if it is a valid package and/or perhaps verify the existence.
05-08-2013

Looks like JavaCompiler.resolveIdent or JavaCompiler.resolveBinaryNameOrIdent is not handling errors correctly. Digging deeper, looks like IdentAttributer.visitMemberSelect (Attr:393) is not detecting errors. But it should. Question is, why is this test not working, Symbol site = visit(node.getExpression(), env); if (site.kind == ERR) return site;
11-06-2013

if using EmptyProcessor.javaxxx fails correctly however this fails badly: javac -processor EmptyProcessor EmptyProcessor.x.y An exception has occurred in the compiler (1.7.0-internal). Please file a bug at the Java Developer Connection (http://java.sun.com/webapps/bugreport) after checking the Bug Parade for duplicates. Include your program and the following diagnostic in your report. Thank you. 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:401) at com.sun.tools.javac.comp.Attr$IdentAttributer.visitMemberSelect(Attr.java:390) at com.sun.tools.javac.tree.JCTree$JCFieldAccess.accept(JCTree.java:1801) at com.sun.tools.javac.comp.Attr.attribIdent(Attr.java:386) at com.sun.tools.javac.main.JavaCompiler.resolveIdent(JavaCompiler.java:711) at com.sun.tools.javac.main.JavaCompiler.resolveBinaryNameOrIdent(JavaCompiler.java:689) at com.sun.tools.javac.main.JavaCompiler.processAnnotations(JavaCompiler.java:1130) at com.sun.tools.javac.main.JavaCompiler.compile(JavaCompiler.java:862) at com.sun.tools.javac.main.Main.compile(Main.java:482) at com.sun.tools.javac.main.Main.compile(Main.java:363) at com.sun.tools.javac.main.Main.compile(Main.java:352) at com.sun.tools.javac.main.Main.compile(Main.java:343) at com.sun.tools.javac.Main.compile(Main.java:76) at com.sun.tools.javac.Main.main(Main.java:61)
11-06-2013