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.