RFR: 8370800: Downgrade cant.attach.type.annotations diagnostics to warnings [v8]

Jan Lahoda jlahoda at openjdk.org
Thu Dec 11 14:35:15 UTC 2025


On Thu, 11 Dec 2025 05:29:48 GMT, Joe Darcy <darcy at openjdk.org> wrote:

>> Liam Miller-Cushon has updated the pull request incrementally with one additional commit since the last revision:
>> 
>>   Complete symbols returned by getAllMembers
>
> Hmm. Catching up on this PR has been on to-do list for a while. Generally there are conditions in the JLS that justify rejecting (or accepting) a program.
> 
> What do the relevant specifications say here?

@jddarcy, I am afraid this is a bit in a gray zone. Consider this sequence of projects/files:

----------- ./prj1/src/A.java
public class A<T> {}

----------- ./prj2/src/B.java
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;
import java.util.List;

public class B {
    private void test (A<String> a) {}
}
@Target(ElementType.TYPE_USE)
@interface TA {}

----------- ./prj3/src/C.java
public class C {
    public B b;
    public void test() {
        b.toString();
    }
}


And the a sequence of compilations like (this is a standing behavior, unrelated to this PR):

$ javac -d prj1/classes prj1/src/A.java 
$ javac -d prj2/classes -cp prj1/classes/ prj2/src/B.java 
$ javac -d prj3/classes -cp prj2/classes/ prj3/src/C.java


note:
- there are no errors
- `A` is not on the compile classpath when compiling `C`, but `B` depends on `A`

When compiling `C`, if javac looked at `B` in the source form, it would be uncompilable, as `A` would not be resolvable. But, since `B` is load from a classfile, javac doesn't proactively check whether `A` exists, until it has a "reason" to look for `A` (at which point it will find out it can't find the definition, and will produce a compile-time error).

AFAIK JLS sees compilation units only it their source form, so strictly speaking, I believe we could always produce an error for any missing class - but the long-standing behavior is that javac only looks for classes/interfaces that are referred to by classfiles if it has a reason to do so.

Now, consider I do this change in `B.java`:

    private void test (A<String> a) {}
=>
    private void test (@TA A<String> a) {}


The compilations now will be (JDK 25):

$ javac -d prj1/classes prj1/src/A.java 
$ javac -d prj2/classes -cp prj1/classes/ prj2/src/B.java 
$ javac -d prj3/classes -cp prj2/classes/ prj3/src/C.java
prj2/classes/B.class: error: Cannot attach type annotations @TA to B.test:
  class file for A not found
1 error


And while technically speaking, I think javac can produce this error, there's a question whether it is reasonable. Especially in this case, where all that was done was adding a type annotation to a type in a private method, and the outcome is that the compilation passed before and now fails.

-------------

PR Comment: https://git.openjdk.org/jdk/pull/28018#issuecomment-3642207754


More information about the compiler-dev mailing list