Class TerminalBuilder

java.lang.Object
org.jline.terminal.TerminalBuilder

public final class TerminalBuilder extends Object
Builder class to create Terminal instances with flexible configuration options.

TerminalBuilder provides a fluent API for creating and configuring terminals with various characteristics. It supports multiple implementation providers and handles the complexities of terminal creation across different platforms and environments.

Terminal Providers

JLine supports multiple terminal provider implementations:

  • FFM - Foreign Function Memory (Java 22+) based implementation
  • JNI - Java Native Interface based implementation
  • Exec - Implementation using external commands
  • Dumb - Fallback-only implementation with limited capabilities (not included in default provider order)

The provider selection can be controlled using the provider(String) method or the org.jline.terminal.provider system property. By default, providers are tried in the order: FFM, JNI, Exec.

Native Library Support

When using providers that require native libraries (such as JNI), the appropriate native library will be loaded automatically. The loading of these libraries is handled by JLineNativeLoader for the JNI provider.

The native library loading can be configured using system properties as documented in JLineNativeLoader.

System vs. Non-System Terminals

TerminalBuilder can create two types of terminals:

  • System terminals - Connected to the actual system input/output streams
  • Non-system terminals - Connected to custom input/output streams

System terminals are created using system(boolean) with a value of true, while non-system terminals require specifying input and output streams using streams(InputStream, OutputStream).

Usage Examples

Creating a default system terminal:

 Terminal terminal = TerminalBuilder.builder()
     .system(true)
     .build();
 

Creating a terminal with custom streams:

 Terminal terminal = TerminalBuilder.builder()
     .name("CustomTerminal")
     .streams(inputStream, outputStream)
     .encoding(StandardCharsets.UTF_8)
     .build();
 

Creating a terminal with a specific provider:

 Terminal terminal = TerminalBuilder.builder()
     .system(true)
     .provider("jni")
     .build();
 

Creating a dumb terminal (with limited capabilities):

 Terminal terminal = TerminalBuilder.builder()
     .dumb(true)
     .build();
 
See Also:
  • Field Details

    • PROP_ENCODING

      public static final String PROP_ENCODING
      See Also:
    • PROP_STDIN_ENCODING

      public static final String PROP_STDIN_ENCODING
      See Also:
    • PROP_STDOUT_ENCODING

      public static final String PROP_STDOUT_ENCODING
      See Also:
    • PROP_STDERR_ENCODING

      public static final String PROP_STDERR_ENCODING
      See Also:
    • PROP_CODEPAGE

      public static final String PROP_CODEPAGE
      See Also:
    • PROP_TYPE

      public static final String PROP_TYPE
      See Also:
    • PROP_PROVIDER

      public static final String PROP_PROVIDER
      See Also:
    • PROP_PROVIDERS

      public static final String PROP_PROVIDERS
      See Also:
    • PROP_PROVIDER_FFM

      public static final String PROP_PROVIDER_FFM
      See Also:
    • PROP_PROVIDER_JNI

      public static final String PROP_PROVIDER_JNI
      See Also:
    • PROP_PROVIDER_EXEC

      public static final String PROP_PROVIDER_EXEC
      See Also:
    • PROP_PROVIDER_DUMB

      public static final String PROP_PROVIDER_DUMB
      See Also:
    • PROP_PROVIDERS_DEFAULT

      public static final String PROP_PROVIDERS_DEFAULT
    • PROP_FFM

      public static final String PROP_FFM
      See Also:
    • PROP_JNI

      public static final String PROP_JNI
      See Also:
    • PROP_EXEC

      public static final String PROP_EXEC
      See Also:
    • PROP_DUMB

      public static final String PROP_DUMB
      See Also:
    • PROP_DUMB_COLOR

      public static final String PROP_DUMB_COLOR
      See Also:
    • PROP_OUTPUT

      public static final String PROP_OUTPUT
      See Also:
    • PROP_OUTPUT_OUT

      public static final String PROP_OUTPUT_OUT
      See Also:
    • PROP_OUTPUT_ERR

      public static final String PROP_OUTPUT_ERR
      See Also:
    • PROP_OUTPUT_OUT_ERR

      public static final String PROP_OUTPUT_OUT_ERR
      See Also:
    • PROP_OUTPUT_ERR_OUT

      public static final String PROP_OUTPUT_ERR_OUT
      See Also:
    • PROP_OUTPUT_FORCED_OUT

      public static final String PROP_OUTPUT_FORCED_OUT
      See Also:
    • PROP_OUTPUT_FORCED_ERR

      public static final String PROP_OUTPUT_FORCED_ERR
      See Also:
    • PROP_DEV_TTY

      public static final String PROP_DEV_TTY
      System property to enable the /dev/tty fallback for creating a terminal when no system stream is connected to a TTY.

      When set to "true" and running on a POSIX system where stdin, stdout, and stderr are all pipes (not TTYs), JLine will attempt to open /dev/tty (the controlling terminal) directly and use it for terminal I/O. This allows interactive features to work even when the process was launched with redirected streams (e.g., via Maven's exec-maven-plugin with the exec:exec goal).

      Defaults to false. Can also be set programmatically via devTty(boolean).

      See Also:
    • PROP_NON_BLOCKING_READS

      public static final String PROP_NON_BLOCKING_READS
      See Also:
    • PROP_SOFTWARE_SIGNALS

      public static final String PROP_SOFTWARE_SIGNALS
      When true (the default), system terminals intercept signal control characters (VINTR, VQUIT, VSUSP) in software and raise the corresponding Terminal.Signal when ISIG is cleared (raw mode). This restores terminal.handle(Signal.INT, ...) behavior that was lost when enterRawMode() started clearing ISIG.

      Set to false for pure native terminal behavior where no automatic signal translation occurs ? the application must handle raw bytes itself.

      The default may change to false in a future release (4.2 or later).

      Since:
      4.1.4
      See Also:
    • PROP_COLOR_DISTANCE

      public static final String PROP_COLOR_DISTANCE
      See Also:
    • PROP_DISABLE_ALTERNATE_CHARSET

      public static final String PROP_DISABLE_ALTERNATE_CHARSET
      See Also:
    • PROP_CLOSE_MODE

      public static final String PROP_CLOSE_MODE
      System property to control terminal stream closure behavior.

      This property controls what happens when code attempts to read from or write to terminal streams (reader, writer, input, output) after the terminal has been closed.

      Two levels of closure enforcement:

      1. Terminal-level: Calling methods on the terminal itself after close() always throws IllegalStateException, regardless of this property.
      2. Stream-level: Using held references to streams obtained before close() is controlled by this property.

      Property values:

      • "strict" (default in JLine 4.x): Accessing closed streams throws ClosedException
      • "warn" (default in JLine 3.x): Accessing closed streams logs a warning but continues to operate
      • "lenient": Accessing closed streams is silently allowed (no warning, no exception)

      Example:

      
       Terminal terminal = TerminalBuilder.terminal();
       NonBlockingReader reader = terminal.reader();  // Get reference before close
       terminal.close();
      
       // This always throws IllegalStateException (terminal-level):
       terminal.reader();  // throws IllegalStateException
      
       // This behavior depends on jline.terminal.closeMode (stream-level):
       reader.read();  // throws ClosedException in "strict" mode
                       // logs warning in "warn" mode
                       // silently continues in "lenient" mode
       
      See Also:
    • PROP_FILE_DESCRIPTOR_CREATION_MODE

      public static final String PROP_FILE_DESCRIPTOR_CREATION_MODE
      See Also:
    • PROP_FILE_DESCRIPTOR_CREATION_MODE_NATIVE

      public static final String PROP_FILE_DESCRIPTOR_CREATION_MODE_NATIVE
      See Also:
    • PROP_FILE_DESCRIPTOR_CREATION_MODE_REFLECTION

      public static final String PROP_FILE_DESCRIPTOR_CREATION_MODE_REFLECTION
      See Also:
    • PROP_FILE_DESCRIPTOR_CREATION_MODE_DEFAULT

      public static final String PROP_FILE_DESCRIPTOR_CREATION_MODE_DEFAULT
    • PROP_REDIRECT_PIPE_CREATION_MODE

      public static final String PROP_REDIRECT_PIPE_CREATION_MODE
      See Also:
    • PROP_REDIRECT_PIPE_CREATION_MODE_NATIVE

      public static final String PROP_REDIRECT_PIPE_CREATION_MODE_NATIVE
      See Also:
    • PROP_REDIRECT_PIPE_CREATION_MODE_REFLECTION

      public static final String PROP_REDIRECT_PIPE_CREATION_MODE_REFLECTION
      See Also:
    • PROP_REDIRECT_PIPE_CREATION_MODE_DEFAULT

      public static final String PROP_REDIRECT_PIPE_CREATION_MODE_DEFAULT
    • PROP_GRAPHEME_CLUSTER

      public static final String PROP_GRAPHEME_CLUSTER
      See Also:
    • PROP_PROBE_TIMEOUT

      public static final String PROP_PROBE_TIMEOUT
      See Also:
    • PROP_DRAIN_TIMEOUT

      public static final String PROP_DRAIN_TIMEOUT
      See Also:
  • Method Details

    • terminal

      public static Terminal terminal() throws IOException
      Returns the default system terminal with automatic configuration.

      This method creates a terminal connected to the system's standard input and output streams, automatically detecting the appropriate terminal type and capabilities for the current environment. It's the simplest way to get a working terminal instance for most applications.

      The terminal is created with default settings, which include:

      • System streams for input and output
      • Auto-detected terminal type
      • System default encoding
      • Native signal handling

      This call is equivalent to: builder().build()

      Important: Terminals should be closed properly using the Closeable.close() method when they are no longer needed in order to restore the original terminal state.

      Example usage:

       try (Terminal terminal = TerminalBuilder.terminal()) {
           terminal.writer().println("Hello, terminal!");
           terminal.flush();
           // Use terminal...
       }
       
      Returns:
      the default system terminal, never null
      Throws:
      IOException - if an error occurs during terminal creation
      See Also:
    • builder

      public static TerminalBuilder builder()
      Creates a new terminal builder instance for configuring and creating terminals.

      This method returns a builder that can be used to configure various aspects of the terminal before creating it. The builder provides a fluent API for setting terminal properties such as name, type, encoding, input/output streams, and more.

      Example usage:

       Terminal terminal = TerminalBuilder.builder()
           .name("MyTerminal")
           .system(true)
           .encoding(StandardCharsets.UTF_8)
           .build();
       
      Returns:
      a new terminal builder instance, never null
      See Also:
    • name

      public TerminalBuilder name(String name)
    • streams

      public TerminalBuilder streams(InputStream in, OutputStream out)
    • system

      public TerminalBuilder system(boolean system)
    • systemOutput

      public TerminalBuilder systemOutput(TerminalBuilder.SystemOutput systemOutput)
      Indicates which standard stream should be used when displaying to the terminal. The default is to use the system output stream. Building a system terminal will fail if one of the stream specified is not linked to the controlling terminal.
      Parameters:
      systemOutput - The mode to choose the output stream.
      Returns:
      The builder.
    • provider

      public TerminalBuilder provider(String provider)
      Forces the usage of the give terminal provider.
      Parameters:
      provider - The TerminalProvider's name to use when creating the Terminal.
      Returns:
      The builder.
    • providers

      public TerminalBuilder providers(String providers)
      Sets the list of providers to try when creating the terminal. If not specified, the system property PROP_PROVIDERS will be used if set. Else, the value PROP_PROVIDERS_DEFAULT will be used.
      Parameters:
      providers - The list of TerminalProvider's names to check when creating the Terminal.
      Returns:
      The builder.
    • jni

      public TerminalBuilder jni(boolean jni)
      Enables or disables the PROP_PROVIDER_JNI/jni terminal provider.

      The JNI provider uses the JLine native library loaded by JLineNativeLoader to access low-level terminal functionality. This provider generally offers the best performance and most complete terminal support.

      If not specified, the system property PROP_JNI will be used if set. If not specified, the provider will be checked for availability.

      The native library loading can be configured using system properties as documented in JLineNativeLoader.

      Parameters:
      jni - true to enable the JNI provider, false to disable it
      Returns:
      this builder
      See Also:
      • JLineNativeLoader
    • exec

      public TerminalBuilder exec(boolean exec)
      Enables or disables the PROP_PROVIDER_EXEC/exec terminal provider. If not specified, the system property PROP_EXEC will be used if set. If not specified, the provider will be checked.
    • ffm

      public TerminalBuilder ffm(boolean ffm)
      Enables or disables the PROP_PROVIDER_FFM/ffm terminal provider. If not specified, the system property PROP_FFM will be used if set. If not specified, the provider will be checked.
    • jansi

      @Deprecated public TerminalBuilder jansi(boolean jansi)
      Deprecated.
      Jansi is no longer used in JLine 4. Native support is provided automatically via FFM or JNI providers.
      No-op retained for backwards compatibility with JLine 3.

      In JLine 3, this method enabled native terminal support via Jansi. JLine 4 replaced Jansi with its own FFM/JNI providers that are used automatically, so this method is no longer needed.

      Parameters:
      jansi - ignored
      Returns:
      this builder
    • jna

      @Deprecated public TerminalBuilder jna(boolean jna)
      Deprecated.
      JNA is no longer used in JLine 4. Native support is provided automatically via FFM or JNI providers.
      No-op retained for backwards compatibility with JLine 3.

      In JLine 3, this method enabled native terminal support via JNA. JLine 4 replaced JNA with its own FFM/JNI providers that are used automatically, so this method is no longer needed.

      Parameters:
      jna - ignored
      Returns:
      this builder
    • dumb

      public TerminalBuilder dumb(boolean dumb)
      Enables or disables the PROP_PROVIDER_DUMB/dumb terminal provider. If not specified, the system property PROP_DUMB will be used if set. If not specified, the provider will be checked.
    • devTty

      public TerminalBuilder devTty(boolean devTty)
      Enables or disables the /dev/tty fallback for creating a terminal when no system stream is connected to a TTY (e.g., when stdin/stdout are pipes).

      When enabled and running on a POSIX system where no system stream (stdin, stdout, stderr) is connected to a terminal, JLine will attempt to open /dev/tty (the controlling terminal) directly and use it for terminal I/O. This allows interactive features like tab completion, syntax highlighting, and history navigation to work even when the process was launched with redirected streams.

      A common use case is running a JLine application via Maven's exec-maven-plugin with the exec:exec goal, which forks a new JVM with piped stdin/stdout.

      If not specified, the system property PROP_DEV_TTY will be used. Defaults to false.

      Parameters:
      devTty - true to enable the /dev/tty fallback
      Returns:
      this builder
    • type

      public TerminalBuilder type(String type)
    • color

      public TerminalBuilder color(boolean color)
    • encoding

      public TerminalBuilder encoding(String encoding) throws UnsupportedCharsetException
      Set the encoding to use for reading/writing from the console. If null (the default value), JLine will automatically select a Charset, usually the default system encoding. However, on some platforms (e.g. Windows) it may use a different one depending on the Terminal implementation.

      Use Terminal.encoding() to get the Charset that should be used for a Terminal.

      This method sets a single encoding for all streams (stdin, stdout, stderr). To set separate encodings for each stream, use stdinEncoding(Charset), stdoutEncoding(Charset), and stderrEncoding(Charset).

      Parameters:
      encoding - The encoding to use or null to automatically select one
      Returns:
      The builder
      Throws:
      UnsupportedCharsetException - If the given encoding is not supported
      See Also:
    • encoding

      public TerminalBuilder encoding(Charset encoding)
      Set the Charset to use for reading/writing from the console. If null (the default value), JLine will automatically select a Charset, usually the default system encoding. However, on some platforms (e.g. Windows) it may use a different one depending on the Terminal implementation.

      Use Terminal.encoding() to get the Charset that should be used to read/write from a Terminal.

      This method sets a single encoding for all streams (stdin, stdout, stderr). To set separate encodings for each stream, use stdinEncoding(Charset), stdoutEncoding(Charset), and stderrEncoding(Charset).

      Parameters:
      encoding - The encoding to use or null to automatically select one
      Returns:
      The builder
      See Also:
    • stdinEncoding

      public TerminalBuilder stdinEncoding(String encoding) throws UnsupportedCharsetException
      Set the encoding to use for reading from standard input. If null (the default value), JLine will use the value from the "stdin.encoding" system property if set, or fall back to the general encoding.
      Parameters:
      encoding - The encoding to use or null to automatically select one
      Returns:
      The builder
      Throws:
      UnsupportedCharsetException - If the given encoding is not supported
      See Also:
    • stdinEncoding

      public TerminalBuilder stdinEncoding(Charset encoding)
      Set the Charset to use for reading from standard input. If null (the default value), JLine will use the value from the "stdin.encoding" system property if set, or fall back to the general encoding.
      Parameters:
      encoding - The encoding to use or null to automatically select one
      Returns:
      The builder
      See Also:
    • stdoutEncoding

      public TerminalBuilder stdoutEncoding(String encoding) throws UnsupportedCharsetException
      Set the encoding to use for writing to standard output. If null (the default value), JLine will use the value from the "stdout.encoding" system property if set, or fall back to the general encoding.
      Parameters:
      encoding - The encoding to use or null to automatically select one
      Returns:
      The builder
      Throws:
      UnsupportedCharsetException - If the given encoding is not supported
      See Also:
    • stdoutEncoding

      public TerminalBuilder stdoutEncoding(Charset encoding)
      Set the Charset to use for writing to standard output. If null (the default value), JLine will use the value from the "stdout.encoding" system property if set, or fall back to the general encoding.
      Parameters:
      encoding - The encoding to use or null to automatically select one
      Returns:
      The builder
      See Also:
    • stderrEncoding

      public TerminalBuilder stderrEncoding(String encoding) throws UnsupportedCharsetException
      Set the encoding to use for writing to standard error. If null (the default value), JLine will use the value from the "stderr.encoding" system property if set, or fall back to the general encoding.
      Parameters:
      encoding - The encoding to use or null to automatically select one
      Returns:
      The builder
      Throws:
      UnsupportedCharsetException - If the given encoding is not supported
      See Also:
    • stderrEncoding

      public TerminalBuilder stderrEncoding(Charset encoding)
      Set the Charset to use for writing to standard error. If null (the default value), JLine will use the value from the "stderr.encoding" system property if set, or fall back to the general encoding.
      Parameters:
      encoding - The encoding to use or null to automatically select one
      Returns:
      The builder
      See Also:
    • attributes

      public TerminalBuilder attributes(Attributes attributes)
      Attributes to use when creating a non system terminal, i.e. when the builder has been given the input and output streams using the streams(InputStream, OutputStream) method or when system(boolean) has been explicitly called with false.
      Parameters:
      attributes - the attributes to use
      Returns:
      The builder
      See Also:
    • size

      public TerminalBuilder size(Size size)
      Initial size to use when creating a non system terminal, i.e. when the builder has been given the input and output streams using the streams(InputStream, OutputStream) method or when system(boolean) has been explicitly called with false.
      Parameters:
      size - the initial size
      Returns:
      The builder
      See Also:
    • nativeSignals

      public TerminalBuilder nativeSignals(boolean nativeSignals)
    • signalHandler

      public TerminalBuilder signalHandler(Terminal.SignalHandler signalHandler)
      Determines the default value for signal handlers. All signals will be mapped to the given handler.
      Parameters:
      signalHandler - the default signal handler
      Returns:
      The builder
    • paused

      public TerminalBuilder paused(boolean paused)
      Initial paused state of the terminal (defaults to false). By default, the terminal is started, but in some cases, one might want to make sure the input stream is not consumed before needed, in which case the terminal needs to be created in a paused state.
      Parameters:
      paused - the initial paused state
      Returns:
      The builder
      See Also:
    • graphemeCluster

      public TerminalBuilder graphemeCluster(boolean graphemeCluster)
      Controls whether mode 2027 (grapheme cluster segmentation) should be enabled on the terminal after construction.

      When enabled, the terminal uses UAX #29 grapheme cluster boundaries for cursor positioning, which allows multi-codepoint characters like ZWJ emoji sequences (e.g., family emoji) to be treated as single display units.

      By default (null), mode 2027 is automatically enabled if the terminal supports it. Set to false to explicitly disable grapheme cluster mode even on terminals that support it.

      This can also be controlled via the system property PROP_GRAPHEME_CLUSTER.

      Parameters:
      graphemeCluster - true to enable, false to disable, or leave unset for auto-detection
      Returns:
      The builder
      See Also:
    • build

      public Terminal build() throws IOException
      Create and configure a Terminal instance according to this builder's settings. If a global terminal override has been set, that instance is returned instead of creating a new one. The method also applies grapheme-cluster mode to the created terminal based on the builder setting or the `org.jline.terminal.graphemeCluster` system property: it may force-enable, disable, or probe-and-enable grapheme-cluster handling on the terminal.
      Returns:
      the configured Terminal instance; never null
      Throws:
      IOException - if terminal creation or configuration fails
    • computeSystemOutput

      public TerminalBuilder.SystemOutput computeSystemOutput()
    • computeType

      public String computeType()
    • computeEncoding

      public Charset computeEncoding()
    • computeStdinEncoding

      public Charset computeStdinEncoding()
    • computeStdoutEncoding

      public Charset computeStdoutEncoding()
    • computeStderrEncoding

      public Charset computeStderrEncoding()
    • getProviders

      public List<TerminalProvider> getProviders(String provider, IllegalStateException exception)
      Get the list of available terminal providers. This list is sorted according to the PROP_PROVIDERS system property.
      Parameters:
      provider - if not null, only this provider will be checked
      exception - if a provider throws an exception, it will be added to this exception as a suppressed exception
      Returns:
      a list of terminal providers
    • setTerminalOverride

      @Deprecated public static void setTerminalOverride(Terminal terminal)
      Deprecated.
      This method is deprecated to discourage its use. It will remain available but users should avoid it when possible and use proper dependency injection instead.
      Allows an application to override the result of build(). The intended use case is to allow a container or server application to control an embedded application that uses a LineReader that uses Terminal constructed with TerminalBuilder.build but provides no public api for setting the LineReader of the Terminal. For example, the sbt build tool uses a LineReader to implement an interactive shell. One of its supported commands is console which invokes the scala REPL. The scala REPL also uses a LineReader and it is necessary to override the Terminal used by the the REPL to share the same Terminal instance used by sbt.

      When this method is called with a non-null Terminal, all subsequent calls to build() will return the provided Terminal regardless of how the TerminalBuilder was constructed. The default behavior of TerminalBuilder can be restored by calling setTerminalOverride with a null Terminal

      Usage of setTerminalOverride should be restricted to cases where it isn't possible to update the api of the nested application to accept a instance.

      Parameters:
      terminal - the Terminal to globally override