Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-7188605

RoundEnvironment.getElementsAnnotatedWith misses @Inherited in JDK 6

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Won't Fix
    • Icon: P4 P4
    • None
    • 6u31
    • tools
    • x86
    • linux

      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.

            darcy Joe Darcy
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: