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

Source generated in last round not visible to other sources

    XMLWordPrintable

Details

    Description

      The following compilation involves an annotation processor that generates a file on the last round. That file defines a symbol that is referenced from the other file in the compilation.

      I expected javac to defer the error for the missing symbol in T.java until after annotation processing is finished, and for the compilation to succeed. Is it expected behaviour that the file generated in the last round is not visible to other files in the compilation?

      (I realize files generated in the last round will not be subject to annotation processing, but that wouldn't be necessary for this compilation to succeed.)

      This may be somewhat related to JDK-6634138 (Source generated in last round not compiled), except here the source generated in the last round *is* compiled, it just isn't visible to the rest of the compilation.

      ```
      import java.io.IOException;
      import java.io.UncheckedIOException;
      import java.io.Writer;
      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;
      import javax.tools.JavaFileObject;

      @SupportedAnnotationTypes("java.lang.Deprecated")
      public class P extends AbstractProcessor {

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

        @Override
        public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
          if (roundEnv.processingOver()) {
            try {
              JavaFileObject jfo = processingEnv.getFiler().createSourceFile("p.L");
              try (Writer w = jfo.openWriter()) {
                w.write("package p; public class L {}");
              }
            } catch (IOException e) {
              throw new UncheckedIOException(e);
            }
          }
          return false;
        }
      }
      ```

      ```
      import p.L;

      @Deprecated
      class T {
        public static void main(String[] args) {
          System.err.println(L.class);
        }
      }
      ```

      The compilation fails with javac 15.0.1+9-18:

      ```
      $ javac -fullversion
      javac full version "15.0.1+9-18"
      $ javac --release 8 P.java
      $ javac --release 8 -processorpath . -processor P T.java
      ...
      T.java:1: error: package p does not exist
      import p.L;
              ^
      warning: File for type 'p.L' created in the last round will not be subject to annotation processing.
      1 error
      1 warning
      ```

      For whatever it's worth, ecj seems to accept this compilation:

      ```
      $ java -fullversion
      java full version "1.8.0_202-b08"
      $ java -jar ecj-4.6.1.jar -source 8 -target 8 -processorpath . -processor P T.java
      ```

      Attachments

        Issue Links

          Activity

            People

              darcy Joe Darcy
              cushon Liam Miller-Cushon
              Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

              Dates

                Created:
                Updated: