JDK-8351573 : Change the default Console implementation back to the built-in one in `java.base` module
  • Type: CSR
  • Component: core-libs
  • Sub-Component: java.io
  • Priority: P4
  • Status: Closed
  • Resolution: Approved
  • Fix Versions: 25
  • Submitted: 2025-03-10
  • Updated: 2025-03-24
  • Resolved: 2025-03-24
Related Reports
CSR :  
Description
Summary
-------
Change `System.console()` to return the Console implementation from the java.base module rather than Console implementation built on JLine.


Problem
-------
The JDK has included a JLine based Console implementation since JDK 20. This Console implementation provides a richer experience and works in virtual terminal environment, e.g. IDEs. The JLine Console implementation was opt-in via a system property on the command line in JDK 20 and JDK 21. It became the default Console implementation in JDK 22.

Although the JLine Console implementation provides a better user experience it has turned out to be difficult to maintain and there are several issues. Examples are terminal escape sequence handling (https://bugs.openjdk.org/browse/JDK-8348052) and signal handling (https://bugs.openjdk.org/browse/JDK-8346805).

Solution
--------
Revert `System.console()` to JDK 21 behavior and return the Console implementation from java.base by default.

Part of the motivation for recent work on Console has been on the efforts to make it easier for new developers to start started and to write a simple interactive programs. JEP 477 "Implicitly Declared Classes and Instance Main Methods" introduced `java.io.IO` which was implemented on `java.io.Console`. The next phase of this work, JEP "Compact Source Files and Instance Main Methods" replaces `java.io.IO` with a new class `java.lang.IO` that will be implemented on the standard streams (System.in/out/err). This removes some of the need for Console to provide rich experience.

If required, the `jdk.console` system property will continue to allow the richer/JLine Console implementation be selected, just as it was in JDK 20 and JDK 21.


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

N/A. Behavior change only.


Comments
Moving to Approved.
24-03-2025

Found this on SO: https://stackoverflow.com/a/75660641 so people might already be depending on it. We could make ProxyingConsole public for custom console implementations, but that may introduce security concerns.
14-03-2025

Thanks for the update. I think it's best that we don't document that jdk.console can set to jdk.internal.le for now but I think we need to think about IDE usage, what would we expect an IDE to configure in order for a program running in the IDE get a Console. It might be that we consider in a follow-up JBS/PR/CSR, it doesn't have to be done here.
14-03-2025

[~alanb], I de-empasized JLine's `opt-in` part, so that the CSR simply brings back the java.base's implementation as the default. I also removed the workaround part in the compatibility risk section not to expose the internal module as a command line setting. There is still a case where `System.console().isTerminal()` retturns false, JShell has its own implementation of Console which does that
13-03-2025

As the compatibility risk section says, the main observable change is that System.console() will return null for cases where it returns a Console in JDK 22+. It brings into question whether there are now any cases where System.console().isTerminal() can return false. It's possible that some developers have got used to System.console() returning a console when in the IDE, the change means they will get null (as they did in JDK 21 and older). We should probably consider whether `-Djdk.console=jdk.internal.le` is the right way to configure the richer console, it would be nice not to have a JDK internal module in the setting.
13-03-2025