FULL PRODUCT VERSION :
java version "1.6.0_33"
Java(TM) SE Runtime Environment (build 1.6.0_33-b03)
Java HotSpot(TM) Server VM (build 20.8-b03, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
Linux jglick-t520 3.2.0-27-generic-pae #43-Ubuntu SMP Fri Jul 6 15:06:05 UTC 2012 i686 i686 i386 GNU/Linux
A DESCRIPTION OF THE PROBLEM :
The Javadoc of RoundEnvironment.getElementsAnnotatedWith specifies that the annotation "may appear directly or be inherited". Yet it seems that in JDK 6 this does not work; an element annotated only by inheritance is not produced. In JDK 7 it does work; the fix (if it can be identified as such) should be backported to a JDK 6 update.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Run the attached test case.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
JDK 7u5 produces:
warning: [options] bootstrap class path not set in conjunction with -source 1.6
getElementsAnnotatedWith(A): [p.Sub]
found by scanning only: p.Sub
1 warning
true
ACTUAL -
JDK 6u33 produces:
getElementsAnnotatedWith(A): []
found by scanning only: p.Sub
true
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
package pkg;
import java.io.File;
import java.io.FileWriter;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Target;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
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.Element;
import javax.lang.model.element.TypeElement;
import javax.lang.model.util.ElementScanner6;
import javax.tools.JavaCompiler;
import javax.tools.JavaCompiler.CompilationTask;
import javax.tools.ToolProvider;
public class Demo {
@Target(ElementType.TYPE) @Inherited @interface A {}
@A public static abstract class Supe {}
public static void main(String[] args) throws Exception {
File source = new File(System.getProperty("java.io.tmpdir"), "Sub.java");
FileWriter w = new FileWriter(source);
w.write("package p; public class Sub extends " + Supe.class.getCanonicalName() + " {}");
w.flush();
w.close();
JavaCompiler javac = ToolProvider.getSystemJavaCompiler();
List<String> opts = Arrays.asList("-source", "6", "-classpath", new File(Demo.class.getProtectionDomain().getCodeSource().getLocation().toURI()).getAbsolutePath());
CompilationTask task = javac.getTask(null, null, null, opts, null, javac.getStandardFileManager(null, null, null).getJavaFileObjects(source));
task.setProcessors(Collections.singleton(new Proc()));
System.out.println(task.call());
}
@SupportedSourceVersion(SourceVersion.RELEASE_6)
@SupportedAnnotationTypes("pkg.Demo.A")
private static class Proc extends AbstractProcessor {
@Override public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
if (roundEnv.processingOver()) {
return false;
}
System.out.println("getElementsAnnotatedWith(A): " + roundEnv.getElementsAnnotatedWith(A.class));
for (Element r : roundEnv.getRootElements()) {
new ElementScanner6<Void,Void>() {
@Override public Void visitType(TypeElement e, Void p) {
if (e.getAnnotation(A.class) != null) {
System.out.println("found by scanning only: " + e);
}
return super.visitType(e, p);
}
}.scan(r);
}
return true;
}
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
Test case also shows the workaround: exhaustively search RoundEnvironment.getRootElements.
java version "1.6.0_33"
Java(TM) SE Runtime Environment (build 1.6.0_33-b03)
Java HotSpot(TM) Server VM (build 20.8-b03, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
Linux jglick-t520 3.2.0-27-generic-pae #43-Ubuntu SMP Fri Jul 6 15:06:05 UTC 2012 i686 i686 i386 GNU/Linux
A DESCRIPTION OF THE PROBLEM :
The Javadoc of RoundEnvironment.getElementsAnnotatedWith specifies that the annotation "may appear directly or be inherited". Yet it seems that in JDK 6 this does not work; an element annotated only by inheritance is not produced. In JDK 7 it does work; the fix (if it can be identified as such) should be backported to a JDK 6 update.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Run the attached test case.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
JDK 7u5 produces:
warning: [options] bootstrap class path not set in conjunction with -source 1.6
getElementsAnnotatedWith(A): [p.Sub]
found by scanning only: p.Sub
1 warning
true
ACTUAL -
JDK 6u33 produces:
getElementsAnnotatedWith(A): []
found by scanning only: p.Sub
true
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
package pkg;
import java.io.File;
import java.io.FileWriter;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Target;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
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.Element;
import javax.lang.model.element.TypeElement;
import javax.lang.model.util.ElementScanner6;
import javax.tools.JavaCompiler;
import javax.tools.JavaCompiler.CompilationTask;
import javax.tools.ToolProvider;
public class Demo {
@Target(ElementType.TYPE) @Inherited @interface A {}
@A public static abstract class Supe {}
public static void main(String[] args) throws Exception {
File source = new File(System.getProperty("java.io.tmpdir"), "Sub.java");
FileWriter w = new FileWriter(source);
w.write("package p; public class Sub extends " + Supe.class.getCanonicalName() + " {}");
w.flush();
w.close();
JavaCompiler javac = ToolProvider.getSystemJavaCompiler();
List<String> opts = Arrays.asList("-source", "6", "-classpath", new File(Demo.class.getProtectionDomain().getCodeSource().getLocation().toURI()).getAbsolutePath());
CompilationTask task = javac.getTask(null, null, null, opts, null, javac.getStandardFileManager(null, null, null).getJavaFileObjects(source));
task.setProcessors(Collections.singleton(new Proc()));
System.out.println(task.call());
}
@SupportedSourceVersion(SourceVersion.RELEASE_6)
@SupportedAnnotationTypes("pkg.Demo.A")
private static class Proc extends AbstractProcessor {
@Override public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
if (roundEnv.processingOver()) {
return false;
}
System.out.println("getElementsAnnotatedWith(A): " + roundEnv.getElementsAnnotatedWith(A.class));
for (Element r : roundEnv.getRootElements()) {
new ElementScanner6<Void,Void>() {
@Override public Void visitType(TypeElement e, Void p) {
if (e.getAnnotation(A.class) != null) {
System.out.println("found by scanning only: " + e);
}
return super.visitType(e, p);
}
}.scan(r);
}
return true;
}
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
Test case also shows the workaround: exhaustively search RoundEnvironment.getRootElements.
- relates to
-
JDK-6498938 Faulty comparison of TypeMirror objects in RoundEnvironment.getElementsAnnotatedWith implementation
-
- Closed
-