United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
JDK-6608214 : Exception throw while analysing a file with error

Details
Type:
Bug
Submit Date:
2007-09-24
Status:
Closed
Updated Date:
2011-05-17
Project Name:
JDK
Resolved Date:
2011-05-17
Component:
tools
OS:
linux
Sub-Component:
javac
CPU:
x86
Priority:
P3
Resolution:
Fixed
Affected Versions:
7
Fixed Versions:

Related Reports
Relates:
Relates:

Sub Tasks

Description
The following exception is thrown while executing the test case below.

java.lang.ClassCastException: com.sun.tools.javac.code.Symbol$TypeSymbol cannot be cast to com.sun.tools.javac.code.Symbol$ClassSymbol
	at com.sun.tools.javac.comp.Check.checkImplementations(Check.java:1558)
	at com.sun.tools.javac.comp.Check.checkImplementations(Check.java:1549)
	at com.sun.tools.javac.comp.Attr.attribClassBody(Attr.java:2736)
	at com.sun.tools.javac.comp.Attr.attribClass(Attr.java:2666)
	at com.sun.tools.javac.comp.Attr.attribClass(Attr.java:2602)
	at com.sun.tools.javac.comp.Attr.attribBounds(Attr.java:480)
	at com.sun.tools.javac.comp.Attr.visitMethodDef(Attr.java:584)
	at com.sun.tools.javac.tree.JCTree$JCMethodDecl.accept(JCTree.java:653)
	at com.sun.tools.javac.comp.Attr.attribTree(Attr.java:372)
	at com.sun.tools.javac.comp.Attr.attribStat(Attr.java:409)
	at com.sun.tools.javac.comp.Attr.attribClassBody(Attr.java:2740)
	at com.sun.tools.javac.comp.Attr.attribClass(Attr.java:2666)
	at com.sun.tools.javac.comp.Attr.attribClass(Attr.java:2602)
	at com.sun.tools.javac.main.JavaCompiler.attribute(JavaCompiler.java:1050)
	at com.sun.tools.javac.main.JavaCompiler.attribute(JavaCompiler.java:1026)
	at com.sun.tools.javac.api.JavacTaskImpl.analyze(JavacTaskImpl.java:369)
	at com.sun.tools.javac.api.JavacTaskImpl.analyze(JavacTaskImpl.java:349)
	at T9999999.main(T9999999.java:61)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	at java.lang.reflect.Method.invoke(Method.java:597)
	at com.sun.javatest.regtest.MainAction$SameVMThread.run(MainAction.java:560)
	at java.lang.Thread.run(Thread.java:619)


/*
 * @test 
 * @bug 9999999
 * @summary a ClassCastException thrown when analyzing incorrect code.
 */

import com.sun.source.util.JavacTask;
import java.io.IOException;
import java.net.URI;
import java.util.Arrays;
import javax.tools.JavaCompiler;
import javax.tools.JavaFileObject;
import javax.tools.SimpleJavaFileObject;
import javax.tools.ToolProvider;

public class T9999999 {
    static class MyFileObject extends SimpleJavaFileObject {
        private String text;
        public MyFileObject(String text) {
            super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE);
            this.text = text;
        }
        @Override
        public CharSequence getCharContent(boolean ignoreEncodingErrors) {
            return text;
        }
    }
    
    public static void main(String[] args) throws IOException {
        final String bootPath = System.getProperty("sun.boot.class.path"); //NOI18N
        final JavaCompiler tool = ToolProvider.getSystemJavaCompiler();
        assert tool != null;
        
        String code = "package test; public class Test<S> { <T extends S & Runnable> void test() {} }";
        
        JavacTask ct = (JavacTask)tool.getTask(null, null, null, Arrays.asList("-bootclasspath",  bootPath, "-Xjcov"), null, Arrays.asList(new MyFileObject(code)));
        
        ct.analyze();
    }
}


I have a revision 252 from:
https://openjdk.dev.java.net/svn/openjdk/jdk/trunk

See also NetBeans issue:
http://www.netbeans.org/issues/show_bug.cgi?id=116436
An error is (correctly) reported before the exception occurs (the error is that the bound combines a type variable and an interface, which is prohibited, according to JLS 4.4). The problem IMO is that the Attr/Check are not prepared for this situation. Presumably because the execution never reaches Attr/Check in the cmd line javac in this case.

                                    

Comments
EVALUATION

This bug is due to javac incorrectly recovering from an erroneous situation. When the following class declaration is compiled

public class Test<S> { <T extends S & Runnable> void test() {} }

Javac succesfully detects an error in the declaration of type variable T (a type variable bound cannot be followed by an interface bound). Since the philosophy of javac is to detect as much errors as possible, even in the presence of errors, the erroneous part of the bounds is discarded (removed from the ast) after the error has been reported so that compilation can proceed. Unfortunately the type info associated to the AST being changed during error recovery is not updated. This cause an internal error to be thrown at a later point. Note that this internal error cannot be detected when running javac in batch mode, but becomes visible when javac is launched through  JSR 199 API (as shown in the example).
                                     
2008-02-11
SUGGESTED FIX

http://sa.sfbay.sun.com/projects/langtools_data/7/6608214/
                                     
2008-02-11
EVALUATION

Problem recreated with build 1.7.0-ea-b24
                                     
2008-01-09
EVALUATION

Problem may be because exception was suppressed in cmd line case, or because execution is progressing further in JSR199 case.
                                     
2008-01-09



Hardware and Software, Engineered to Work Together