Null-checking System.console() is not a reliable way to detect if the console
is connected to a terminal.
See JDK 22 Release Note: JLine As The Default Console Provider:
System.console()now returns aConsoleobject when the standard streams are redirected or connected to a virtual terminal. In prior releases,System.console()returnednullfor these cases. This change may impact code that uses the return fromSystem.console()to test if the VM is connected to a terminal. If needed, running with-Djdk.console=java.basewill restore older behavior where the console is only returned when it is connected to a terminal.
A new method
Console.isTerminal()has been added to test if console is connected to a terminal.
and JDK 25 release note Release Note: Default Console Implementation No Longer Based On JLine:
The default Console obtained via
System.console()is no longer based on JLine. Since JDK 20, the JDK has included a JLine-based Console implementation, offering a richer user experience and better support for virtual terminal environments, such as IDEs. This implementation was initially opt-in via a system property in JDK 20 and JDK 21 and became the default in JDK 22. However, maintaining the JLine-based Console proved challenging. As a result, in JDK 25, it has reverted to being opt-in, as it was in JDK 20 and JDK 21.
To prepare for this change while remaining compatible with JDK versions prior to
JDK 22, consider using reflection to call Console#isTerminal on JDK versions
that support it:
@SuppressWarnings("SystemConsoleNull") // https://errorprone.info/bugpattern/SystemConsoleNull
private static boolean systemConsoleIsTerminal() {
Console systemConsole = System.console();
if (Runtime.version().feature() < 22 || systemConsole == null) {
return systemConsole != null;
}
try {
return (Boolean) Console.class.getMethod("isTerminal").invoke(systemConsole);
} catch (ReflectiveOperationException e) {
throw new LinkageError(e.getMessage(), e);
}
}
Suppress false positives by adding the suppression annotation @SuppressWarnings("SystemConsoleNull") to the enclosing element.