Skip to content

ConsoleAppender: support JLine's org.jline.jansi.AnsiConsole for <withJansi> - #1050

Merged
ceki merged 1 commit into
qos-ch:masterfrom
seonwooj0810:fix/issue-1043-jansi-jline-classname
Jul 24, 2026
Merged

ConsoleAppender: support JLine's org.jline.jansi.AnsiConsole for <withJansi>#1050
ceki merged 1 commit into
qos-ch:masterfrom
seonwooj0810:fix/issue-1043-jansi-jline-classname

Conversation

@seonwooj0810

Copy link
Copy Markdown
Contributor

Fixes #1043

Root cause

Jansi was migrated from FuseSource (org.fusesource.jansi) to JLine (org.jline.jansi), which changed the package of AnsiConsole. ConsoleAppender.wrapWithJansi(...) loaded the FuseSource class name by reflection (org.fusesource.jansi.AnsiConsole), so for users who now have only the JLine Jansi artifact on the classpath, <withJansi> silently degrades to the plain stream:

WARN in ch.qos.logback.core.ConsoleAppender[STDOUT] - Failed to create AnsiPrintStream. Falling back on the default stream.
java.lang.ClassNotFoundException: org.fusesource.jansi.AnsiConsole

Change

  • ConsoleAppender now probes an ordered list of candidate class names — JLine org.jline.jansi.AnsiConsole first, then the legacy FuseSource org.fusesource.jansi.AnsiConsole — via a small loadAnsiConsoleClass(ClassLoader) helper. JLine repackages the same Jansi 2 API (out()/err()/systemInstall()), so the existing reflective method lookup is unchanged.
  • Behavior is unchanged for existing FuseSource users (they hit the fallback candidate).

This matches the approach suggested in the issue thread ("try the new class name and fall back to the old one").

Tests

  • New ConsoleAppenderJansiClassResolutionTest (dependency-free, uses a custom ClassLoader to simulate each environment): verifies JLine is preferred when both are present, falls back to FuseSource when JLine is absent, and throws ClassNotFoundException when neither is available. These fail against the old hard-coded lookup in a JLine-only environment and pass after the change.
  • Existing JansiConsoleAppenderTest (FuseSource on the classpath) still passes, confirming the legacy path is preserved.

Verification done: built and ran mvn -pl logback-core test -Dtest=ConsoleAppenderJansiClassResolutionTest (3 passed) and mvn -pl logback-core-blackbox test -Dtest=JansiConsoleAppenderTest (2 passed) on JDK 25 with --release 17.

Note: the JPMS module-info / OSGi Import-Package descriptors still reference org.fusesource.jansi only; I kept this PR to the runtime reflective lookup to stay minimal, but happy to add JLine to those optional requirements as a follow-up if desired.

…ansi>

Jansi was migrated from FuseSource (org.fusesource.jansi) to JLine
(org.jline.jansi), which changed the package of AnsiConsole. Because
ConsoleAppender loaded the FuseSource class name by reflection, <withJansi>
silently fell back to the plain stream ("Failed to create AnsiPrintStream",
ClassNotFoundException: org.fusesource.jansi.AnsiConsole) for users who now
have only the JLine Jansi artifact on the classpath.

Probe the JLine coordinates first and fall back to the legacy FuseSource
ones, so <withJansi> keeps working with either artifact.

Fixes qos-ch#1043

Signed-off-by: seonwoo_jung <79202163+seonwooj0810@users.noreply.github.com>
@ceki
ceki merged commit 693c6bc into qos-ch:master Jul 24, 2026
1 check passed
@ceki ceki self-assigned this Jul 25, 2026
@ceki ceki added the DONE label Jul 25, 2026
@ceki ceki added this to the 1.6.1 milestone Jul 25, 2026
@ceki

ceki commented Jul 25, 2026

Copy link
Copy Markdown
Member

@seonwooj0810 Thank you for this PR. Its conciseness was a plus.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ConsoleAppender's JANSI native support (withJansi) do not work after Jansi migration from FuseSource to JLine

2 participants