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

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

    Details

    • Type: Bug
    • Status: Resolved
    • Priority: P4
    • Resolution: Fixed
    • Affects Version/s: None
    • Fix Version/s: 11
    • Component/s: tools
    • Labels:
      None
    • Subcomponent:
    • Resolved In Build:
      b01

      Description

      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: []

        Attachments

          Issue Links

            Activity

              People

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

                Dates

                • Created:
                  Updated:
                  Resolved: