JDK-8256826 : Source generated in last round not visible to other sources
  • Type: Bug
  • Component: tools
  • Sub-Component: javac
  • Affected Version: 15
  • Priority: P4
  • Status: Open
  • Resolution: Unresolved
  • Submitted: 2020-11-21
  • Updated: 2024-01-31
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
Other
tbdUnresolved
Related Reports
Relates :  
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
```
Comments
If the processor P and client T are changed to refer to a generated file in the unnamed package, the compilation succeeds without error, having the generated file in a different package looks involved in the compilation error.
31-01-2024

Reproduced observed behavior under JDK 22.
31-01-2024