Java Solaris Communities Sun Store Join SDN My Profile Why Join?
 
Bug Database
Bug Detail
Quick Lists
Top 25 Bugs
Top 25 RFE's
Recently Closed Bugs
Printable Page Printable Page


Bug Database
Bug ID: 6468404
Votes 0
Synopsis ExecutableElement.getParameters() uses raw type for class loaded from -g bytecode
Category java:compiler
Reported Against b98
Release Fixed 7(b03), 6u1(b02) (Bug ID:2144594)
State 10-Fix Delivered, bug
Priority: 4-Low
Related Bugs 6379520 , 6468813 , 6499165 , 6500594
Submit Date 07-SEP-2006
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.
Posted Date : 2006-09-07 20:08:24.0
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.
Evaluation
Looks like a bug in the code for reading variable names in ClassReader.
Posted Date : 2006-09-08 21:12:41.0

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.
Posted Date : 2006-10-17 02:57:28.0

I also fixed a number of regression tests which had their golden files
affected by 6379520.
Posted Date : 2006-10-17 03:02:14.0
Comments
  
  Include a link with my name & email   


PLEASE NOTE: JDK6 is formerly known as Project Mustang