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

[REDO BACKPORT] type annotations are not visible to javac plugins across compilation boundaries

XMLWordPrintable

    • b23

      javac fails to associate type annotations with TypeMirrors for some symbols loaded from the classpath, which prevents plugins from accessing those annotations across compilation boundaries. The annotations are present if the same symbol is compiled from source in the compilation where the plugin runs.

      === ./test/B.java
      abstract class B extends A {}
      === ./test/A.java
      import java.lang.annotation.ElementType;
      import java.util.List;
      import java.lang.annotation.Retention;
      import java.lang.annotation.RetentionPolicy;
      import java.lang.annotation.Target;

      @Target(ElementType.TYPE_USE)
      @Retention(RetentionPolicy.RUNTIME)
      @interface TypeAnnotation {}

      abstract class A implements List<@TypeAnnotation String> {}
      === ./plugin/p/P.java
      package p;

      import com.sun.source.util.JavacTask;
      import com.sun.source.util.Plugin;
      import com.sun.source.util.TaskEvent;
      import com.sun.source.util.TaskListener;
      import javax.lang.model.element.TypeElement;
      import javax.lang.model.type.DeclaredType;
      import javax.lang.model.type.TypeMirror;

      public class P implements Plugin {

        @Override
        public String getName() {
          return "P";
        }

        @Override
        public void init(JavacTask javacTask, String... strings) {
          javacTask.addTaskListener(
              new TaskListener() {
                @Override
                public void finished(TaskEvent e) {
                  if (e.getKind() != TaskEvent.Kind.ENTER) {
                    return;
                  }
                  TypeElement b = javacTask.getElements().getTypeElement("B");
                  for (TypeMirror i :
                      ((TypeElement) ((DeclaredType) b.getSuperclass()).asElement()).getInterfaces()) {
                    System.err.printf("%s %s\n", i, i.getAnnotationMirrors());
                  }
                }
              });
        }
      }
      === ./plugin/module-info.java
      module p {
        requires transitive jdk.compiler;
        provides com.sun.source.util.Plugin with p.P;
      }
      ===

      $ javac $(find plugin -name '*.java')

      # when both compilation units are compiled from source, the type annotations are visible

      $ javac --processor-module-path plugin -Xplugin:P test/A.java test/B.java
      java.util.List<@TypeAnnotation java.lang.String>
      java.util.List<@TypeAnnotation java.lang.String>

      # when 'A' is loaded from the classpath, the type annotations on its supertype are not visible

      $ javac --processor-module-path plugin -Xplugin:P -classpath test test/B.java
      java.util.List<java.lang.String>

            cushon Liam Miller-Cushon
            cushon Liam Miller-Cushon
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated: