JDK-8361911 : System.console() should only be available for interactive terminal
  • Type: CSR
  • Component: core-libs
  • Sub-Component: java.lang
  • Priority: P4
  • Status: Closed
  • Resolution: Approved
  • Fix Versions: 21-pool,25-pool,26
  • Submitted: 2025-07-10
  • Updated: 2025-08-16
  • Resolved: 2025-08-16
Related Reports
CSR :  
Description
Summary
-------

`System.console()` should return a non-null `Console` instance only when both standard input and output are connected to a terminal.

Problem
-------
The current `java.io.Console` class description reads:
```
If this virtual machine has a console then it is represented by a unique instance
of this class which can be obtained by invoking the System.console() method.
If no console device is available then an invocation of that method will return null.
```
Thus, it is up to the implementation to determine under what conditions a `Console` instance is returned. In recent JDK releases, a JLine-based `Console` implementation ("JLine provider") is available, which provides a `Console` instance even when standard input and/or output is redirected. On the contrary, the built-in `Console` implementation in the `java.base` module ("base provider") never returns a `Console` instance when I/O is redirected. (That is, `System.console()` returns null.) The user can choose the console provider by specifying the `-Djdk.console=jdk.internal.le` or `-Djdk.console=java.base` options on the command line.

Here is a chart that describes the timeline of the implementation changes.

| JDK version     | Description | Issue ID |
| ----------- | ----------- | --------- |
| JDK 19 and earlier | base provider only | N/A |
| JDK 20 | base provider default, JLine provider opt-in | JDK-8299689 |
| JDK 22 | JLine provider default, base provider opt-in | JDK-8308591 |
| JDK 25 | base provider default, JLine provider opt-in | JDK-8351435 |

The JLine provider was the default in JDK 22 through JDK 24, and so in those releases, `System.console()` would return a non-null `Console` instance when I/O was redirected. If the user has requested the JLine provider, this behavior can occur in any release from JDK 20 onwards.

The ability to obtain a non-null `Console` instance when I/O has been redirected is problematic, mainly because of the `readPassword()` method. This method can issue a prompt and then read a password with echoing disabled. If I/O has been redirected, the prompt might not be visible to the user, or the password might be read without echoing disabled. Either behavior seems inadvisable from a security perspective.

Solution
--------

Enforce the rule that `System.console()` returns a non-null `Console` instance only when both standard input and standard output are connected to a terminal (that is, in the absence of redirection). If I/O has been redirected, `System.console()` always returns null. This behavior should be consistent regardless of whether the base provider or the JLine provider is in use.

Specification
-------------

N/A. This is a behavioral change only.


Comments
Moving to Approved.
16-08-2025

Moving to Provisional, not Approved.
15-08-2025

[~naoto] Thanks for the link, that is important for this CSR.
14-08-2025

[~alanb], the clarification of isTerminal() is in place with the issue: https://bugs.openjdk.org/browse/JDK-8361972
12-08-2025

I think this is okay but we may need to follow-up with clarification to the Console::isTerminal method. Developers will ask if there are any cases where it may return false.
12-08-2025