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

Filer should warn if processors redefine symbols from the classpath or sourcepath

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Fixed
    • Icon: P4 P4
    • 11
    • None
    • tools
    • None
    • b01

      javac should emit a warning if an annotation processor generates a class that overwrites/overrides a class that is present on the classpath or sourcepath.

      Using annotation processing to redefine a symbol on the classpath or sourcepath allows other annotation processors to see different well-formed definitions of the same symbol during different processing rounds of a single compilation.

      Related:
      * TODO in JavacFiler: http://hg.openjdk.java.net/jdk/jdk/file/a9405d9ca8a8/src/jdk.compiler/share/classes/com/sun/tools/javac/processing/JavacFiler.java#l715
      * compiler-dev thread: http://mail.openjdk.java.net/pipermail/compiler-dev/2017-December/011403.html

      Demo:

      === ./P.java
      import static java.nio.charset.StandardCharsets.UTF_8;

      import java.io.IOError;
      import java.io.IOException;
      import java.io.OutputStream;
      import java.util.Set;
      import javax.annotation.processing.AbstractProcessor;
      import javax.annotation.processing.RoundEnvironment;
      import javax.annotation.processing.SupportedAnnotationTypes;
      import javax.lang.model.SourceVersion;
      import javax.lang.model.element.TypeElement;

      @SupportedAnnotationTypes("*")
      public class P extends AbstractProcessor {

        @Override
        public SourceVersion getSupportedSourceVersion() {
          return SourceVersion.latestSupported();
        }

        private int round = 0;

        @Override
        public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
          round++;

          TypeElement a = processingEnv.getElementUtils().getTypeElement("A");
          System.err.println(
              "round " + round + ", a has annotations: [" + a.getAnnotationMirrors() + "]");

          if (round == 1) {
            try (OutputStream os = processingEnv.getFiler().createSourceFile("A").openOutputStream()) {
              os.write("class A {}".getBytes(UTF_8));
            } catch (IOException e) {
              throw new IOError(e);
            }
          }
          return false;
        }
      }
      === ./A.java
      @Deprecated
      class A {}
      === ./B.java
      class B {
        A a;
      }
      ===

      $ javac A.java
      $ javac -sourcepath : -processor P B.java -s gensource
      round 1, a has annotations: [@java.lang.Deprecated]
      round 2, a has annotations: []
      round 3, a has annotations: []

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

              Created:
              Updated:
              Resolved: