United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
Bug ID: JDK-6468404 ExecutableElement.getParameters() uses raw type for class loaded from -g bytecode
JDK-6468404 : ExecutableElement.getParameters() uses raw type for class loaded from -g bytecode

Details
Type:
Bug
Submit Date:
2006-09-07
Status:
Closed
Updated Date:
2011-03-08
Project Name:
JDK
Resolved Date:
2011-03-08
Component:
tools
OS:
solaris_9,linux
Sub-Component:
javac
CPU:
x86,sparc
Priority:
P4
Resolution:
Fixed
Affected Versions:
2.0,6
Fixed Versions:

Related Reports
Backport:
Duplicate:
Duplicate:

Sub Tasks

Description
Create and compile a test class with JDK 6:

---%<---
import java.io.IOException;
import java.net.URI;
import java.util.Arrays;
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.ExecutableElement;
import javax.lang.model.element.TypeElement;
import javax.lang.model.type.ExecutableType;
import javax.tools.JavaCompiler;
import javax.tools.JavaFileObject;
import javax.tools.SimpleJavaFileObject;
import javax.tools.ToolProvider;
public class Test {
    public static void main(String[] args) throws Exception {
        String dest = System.getProperty("java.io.tmpdir");
        class DummyFO extends SimpleJavaFileObject {
            String n;
            public DummyFO(String n) {
                super(URI.create("nowhere:/" + n + ".java"), JavaFileObject.Kind.SOURCE);
                this.n = n;
            }
            public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException {
                return "public class " + n + " {" + n + "(java.util.List<String> l) {}}";
            }
        }
        System.out.println("Compiling with sources:");
        JavaCompiler.CompilationTask task = ToolProvider.getSystemJavaCompiler().getTask(
                null, null, null,
                Arrays.asList("-d", dest),
                null, Collections.singleton(new DummyFO("C")));
        task.setProcessors(Collections.singleton(new P()));
        task.call();
        System.out.println("Compiling with binaries w/o -g:");
        task = ToolProvider.getSystemJavaCompiler().getTask(
                null, null, null,
                Arrays.asList("-classpath", dest, "-d", dest),
                null, Collections.singleton(new DummyFO("Dummy")));
        task.setProcessors(Collections.singleton(new P()));
        task.call();
        task = ToolProvider.getSystemJavaCompiler().getTask(
                null, null, null,
                Arrays.asList("-d", dest, "-g"),
                null, Collections.singleton(new DummyFO("C")));
        task.call();
        System.out.println("Compiling with binaries w/ -g:");
        task = ToolProvider.getSystemJavaCompiler().getTask(
                null, null, null,
                Arrays.asList("-classpath", dest, "-d", dest),
                null, Collections.singleton(new DummyFO("Dummy")));
        task.setProcessors(Collections.singleton(new P()));
        task.call();
    }
    @SupportedAnnotationTypes("*")
    @SupportedSourceVersion(SourceVersion.RELEASE_6)
    static class P extends AbstractProcessor {
        boolean ran = false;
        public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
            if (!ran) {
                ran = true;
                ExecutableElement m = (ExecutableElement) processingEnv.getElementUtils().getTypeElement("C").getEnclosedElements().get(0);
                System.out.println("method: " + m);
                System.out.println("parameters[0]: " + m.getParameters().get(0).asType());
                System.out.println("parameterTypes[0]: " + ((ExecutableType) m.asType()).getParameterTypes().get(0));
            }
            return true;
        }
    }
}
---%<---

Expected output:

---%<---
Compiling with sources:
method: C(java.util.List<java.lang.String>)
parameters[0]: java.util.List<java.lang.String>
parameterTypes[0]: java.util.List<java.lang.String>
Compiling with binaries w/o -g:
method: C(java.util.List<java.lang.String>)
parameters[0]: java.util.List<java.lang.String>
parameterTypes[0]: java.util.List<java.lang.String>
Compiling with binaries w/ -g:
method: C(java.util.List<java.lang.String>)
parameters[0]: java.util.List<java.lang.String>
parameterTypes[0]: java.util.List<java.lang.String>
---%<---

Actual output w/ -showversion:

---%<---
java version "1.6.0-rc"
Java(TM) SE Runtime Environment (build 1.6.0-rc-b98)
Java HotSpot(TM) Client VM (build 1.6.0-rc-b98, mixed mode, sharing)

Compiling with sources:
method: C(java.util.List<java.lang.String>)
parameters[0]: java.util.List<java.lang.String>
parameterTypes[0]: java.util.List<java.lang.String>
Compiling with binaries w/o -g:
method: C(java.util.List<java.lang.String>)
parameters[0]: java.util.List<java.lang.String>
parameterTypes[0]: java.util.List<java.lang.String>
Compiling with binaries w/ -g:
method: C(java.util.List<java.lang.String>)
parameters[0]: java.util.List
parameterTypes[0]: java.util.List<java.lang.String>
---%<---

When loading the class from bytecode compiled with -g, the ExecutableElement for <init>(List<String>) reports parameters[0].asType() as being List, whereas it should be List<String>. ExecutableType gets it right.

But the bug does not occur if you create the parse tree from sources; or if you create it from classes compiled without -g.

                                    

Comments
WORK AROUND

Always use ExecutableType.getParameterTypes(), not ExecutableElement.getParameters(), if you need to know exact types of method/constructor params for classes which might be in the classpath rather than the compilation unit.
                                     
2006-09-07
EVALUATION

Looks like a bug in the code for reading variable names in ClassReader.
                                     
2006-09-08
EVALUATION

I rewrote the submitted test case to use StandardJavaFileManager.setLocation() and
I noticed that the locations are reset during annotation processing and subsequent
calls to getTask.

The problem is that locations are stored in a com.sun.javac.util.Paths instance
which is discarded when a new context is supplied to DefaultFileManager.  So
I added a setContext method to Paths.
                                     
2006-10-17
EVALUATION

I also fixed a number of regression tests which had their golden files
affected by 6379520.
                                     
2006-10-17
SUGGESTED FIX

Webrev of changes: http://sa.sfbay/projects/langtools/bugid_summary.pl?bugid=6468404
See also attachment 6468404.tar.gz.
                                     
2006-10-20



Hardware and Software, Engineered to Work Together