The following example shows that javac fails to report an error for a compilation with an empty bootclasspath (or system module path) if annotation processing is enabled.
An error should be reported regardless of whether annotation processing is enabled. I suspect this is a bug related to deferred diagnostic handling with annotation processors, and the Abort that's being thrown is causing a deferred diagnostic handler to get lost somewhere.
The bug reproduces for newer language levels and --system instead of -bootclasspath, I used -bootclasspath for the repro because it's easier to demonstrate than to create an empty system module path.
=== T.java
class T {
String s;
}
=== P.java
import java.util.Set;
import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.RoundEnvironment;
import javax.lang.model.element.TypeElement;
public class P extends AbstractProcessor {
@Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
return false;
}
}
===
$ javac -fullversion
javac full version "21-ea+25-2212"
# without annotation processing enabled, javac reports the expected compiler.err.no.java.lang error
$ javac T.java -source 8 -target 8 -bootclasspath empty -XDrawDiagnostics
- compiler.warn.option.obsolete.source: 8
- compiler.warn.option.obsolete.target: 8
- compiler.warn.option.obsolete.suppression
- compiler.err.no.java.lang
1 error
3 warnings
# with annotation processing enabled, javac doesn't report an error, and finishes with exit code 0, but the compilation fails internally and doesn't produce output
$ javac T.java -source 8 -target 8 -bootclasspath empty -XDrawDiagnostics -processor P
- compiler.warn.option.obsolete.source: 8
- compiler.warn.option.obsolete.target: 8
- compiler.warn.option.obsolete.suppression
3 warnings
$ echo $?
0
# adding -XDdev shows an internal Abort is being thrown, but with processing enabled the diagnostic isn't getting emitted before the compilation completes:
$ javac T.java -source 8 -target 8 -bootclasspath empty -XDrawDiagnostics -processor P -XDdev
- compiler.warn.option.obsolete.source: 8
- compiler.warn.option.obsolete.target: 8
- compiler.warn.option.obsolete.suppression
com.sun.tools.javac.util.Abort
at jdk.compiler/com.sun.tools.javac.comp.TypeEnter$ImportsPhase.importJavaLang(TypeEnter.java:337)
at jdk.compiler/com.sun.tools.javac.comp.TypeEnter$ImportsPhase.resolveImports(TypeEnter.java:388)
at jdk.compiler/com.sun.tools.javac.comp.TypeEnter$ImportsPhase.runPhase(TypeEnter.java:324)
at jdk.compiler/com.sun.tools.javac.comp.TypeEnter$Phase.doCompleteEnvs(TypeEnter.java:285)
at jdk.compiler/com.sun.tools.javac.comp.TypeEnter$Phase.completeEnvs(TypeEnter.java:254)
at jdk.compiler/com.sun.tools.javac.comp.TypeEnter.complete(TypeEnter.java:201)
at jdk.compiler/com.sun.tools.javac.code.Symbol.complete(Symbol.java:682)
at jdk.compiler/com.sun.tools.javac.code.Symbol$ClassSymbol.complete(Symbol.java:1412)
at jdk.compiler/com.sun.tools.javac.comp.Enter.complete(Enter.java:614)
at jdk.compiler/com.sun.tools.javac.comp.Enter.main(Enter.java:591)
at jdk.compiler/com.sun.tools.javac.main.JavaCompiler.enterTrees(JavaCompiler.java:1060)
at jdk.compiler/com.sun.tools.javac.main.JavaCompiler.compile(JavaCompiler.java:935)
at jdk.compiler/com.sun.tools.javac.main.Main.compile(Main.java:319)
at jdk.compiler/com.sun.tools.javac.main.Main.compile(Main.java:178)
at jdk.compiler/com.sun.tools.javac.Main.compile(Main.java:64)
at jdk.compiler/com.sun.tools.javac.Main.main(Main.java:50)
3 warnings
An error should be reported regardless of whether annotation processing is enabled. I suspect this is a bug related to deferred diagnostic handling with annotation processors, and the Abort that's being thrown is causing a deferred diagnostic handler to get lost somewhere.
The bug reproduces for newer language levels and --system instead of -bootclasspath, I used -bootclasspath for the repro because it's easier to demonstrate than to create an empty system module path.
=== T.java
class T {
String s;
}
=== P.java
import java.util.Set;
import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.RoundEnvironment;
import javax.lang.model.element.TypeElement;
public class P extends AbstractProcessor {
@Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
return false;
}
}
===
$ javac -fullversion
javac full version "21-ea+25-2212"
# without annotation processing enabled, javac reports the expected compiler.err.no.java.lang error
$ javac T.java -source 8 -target 8 -bootclasspath empty -XDrawDiagnostics
- compiler.warn.option.obsolete.source: 8
- compiler.warn.option.obsolete.target: 8
- compiler.warn.option.obsolete.suppression
- compiler.err.no.java.lang
1 error
3 warnings
# with annotation processing enabled, javac doesn't report an error, and finishes with exit code 0, but the compilation fails internally and doesn't produce output
$ javac T.java -source 8 -target 8 -bootclasspath empty -XDrawDiagnostics -processor P
- compiler.warn.option.obsolete.source: 8
- compiler.warn.option.obsolete.target: 8
- compiler.warn.option.obsolete.suppression
3 warnings
$ echo $?
0
# adding -XDdev shows an internal Abort is being thrown, but with processing enabled the diagnostic isn't getting emitted before the compilation completes:
$ javac T.java -source 8 -target 8 -bootclasspath empty -XDrawDiagnostics -processor P -XDdev
- compiler.warn.option.obsolete.source: 8
- compiler.warn.option.obsolete.target: 8
- compiler.warn.option.obsolete.suppression
com.sun.tools.javac.util.Abort
at jdk.compiler/com.sun.tools.javac.comp.TypeEnter$ImportsPhase.importJavaLang(TypeEnter.java:337)
at jdk.compiler/com.sun.tools.javac.comp.TypeEnter$ImportsPhase.resolveImports(TypeEnter.java:388)
at jdk.compiler/com.sun.tools.javac.comp.TypeEnter$ImportsPhase.runPhase(TypeEnter.java:324)
at jdk.compiler/com.sun.tools.javac.comp.TypeEnter$Phase.doCompleteEnvs(TypeEnter.java:285)
at jdk.compiler/com.sun.tools.javac.comp.TypeEnter$Phase.completeEnvs(TypeEnter.java:254)
at jdk.compiler/com.sun.tools.javac.comp.TypeEnter.complete(TypeEnter.java:201)
at jdk.compiler/com.sun.tools.javac.code.Symbol.complete(Symbol.java:682)
at jdk.compiler/com.sun.tools.javac.code.Symbol$ClassSymbol.complete(Symbol.java:1412)
at jdk.compiler/com.sun.tools.javac.comp.Enter.complete(Enter.java:614)
at jdk.compiler/com.sun.tools.javac.comp.Enter.main(Enter.java:591)
at jdk.compiler/com.sun.tools.javac.main.JavaCompiler.enterTrees(JavaCompiler.java:1060)
at jdk.compiler/com.sun.tools.javac.main.JavaCompiler.compile(JavaCompiler.java:935)
at jdk.compiler/com.sun.tools.javac.main.Main.compile(Main.java:319)
at jdk.compiler/com.sun.tools.javac.main.Main.compile(Main.java:178)
at jdk.compiler/com.sun.tools.javac.Main.compile(Main.java:64)
at jdk.compiler/com.sun.tools.javac.Main.main(Main.java:50)
3 warnings