JDK-8297226 : Console should be usable in jshell and other environments
  • Type: CSR
  • Component: core-libs
  • Sub-Component: java.io
  • Priority: P4
  • Status: Proposed
  • Resolution: Unresolved
  • Fix Versions: 20
  • Submitted: 2022-11-17
  • Updated: 2022-11-21
Related Reports
CSR :  
Description
Summary
-------

Provide a mechanism for plugging-in a custom `java.io.Console` implementation.

Problem
-------

`java.io.Console` instance is only available when the JVM is attached to an OS provided interactive console. Otherwise `System.console()` returns `null`. This is not very useful for applications such as `jshell` in which the debugee process is not attached to a console.

Solution
--------

Provide a means to utilize custom `Console` implementations. A custom implementation of `Console` can be returned with `System.console()` even when the JVM is not attached to the underlying platform's TTY. This also allows replacing the default Console implementation with functionality-rich `jline`.

The custom `Console` implementation is searched using `ServiceLoader` with non-public `jdk.internal.io.JdkConsoleProvider` interface. A new non-public system property `jdk.console` designates the module name which the `System.console()` returns the implementation. `jdk.internal.le` and `jdk.jshell` are only allowed to provide the implementation for security purposes. The Console implementation based on `jline` is the default Console if the `jdk.internal.le` module is available. The following chart depicts which instance is returned from `System.console()` call:

|       | w/ `jdk.internal.le`  | w/o `jdk.internal.le`
| ----------- | ----------- | ----------- |
| w/ TTY      | `jline` Console       | built-in Console
| w/o TTY   | `jline` Console        | (null)

Specifying the` jdk.console` system property overrides the above default, ie., 
```
-Djdk.console=jdk.jshell
```
will look for the implementation in `jdk.jshell` module. If there is one, the above default Console will be replaced with the one in `jdk.jshell` module.

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

Remove `final` from the class definition of `java.io.Console` class in order for creating a proxying subclass of it.


Comments
Moving to Provisional for an indeterminate release.
18-11-2022

Implementations do not directly extend `java.io.Console`. Instead they implement a proxy delegate interface `jdk.internal.io.JdkConsole` that resides in `java.base` module. However, since the inteface is in `java.base` I don't think it can depend on other modules, thus cannot be `seal`ed.
18-11-2022

Moving to Provisional, not Approved. For a change in this vein, can the Console class be sealed?
18-11-2022