This is an automated email from the ASF dual-hosted git repository. davsclaus pushed a commit to branch resolve-24481 in repository https://gitbox.apache.org/repos/asf/camel.git
commit 375ee22670d7b4d43278d17680591308ec0bad9c Merge: 145871e9c5b0 2dc5de5463cf Author: Claus Ibsen <[email protected]> AuthorDate: Tue Jul 7 07:58:51 2026 +0200 Merge branch 'main' into CAMEL-23839 (resolve conflicts) Resolve merge conflicts in Theme.java caused by PRs #24475 and #24482 landing on main after this branch was created. Keeps both the ThemeMode enum (from this PR) and the loadCssResource classloader fix (from main). Co-Authored-By: Claude Opus 4.6 <[email protected]> Signed-off-by: Claus Ibsen <[email protected]> .../ROOT/pages/camel-4x-upgrade-guide-4_22.adoc | 3 + .../modules/ROOT/pages/camel-jbang-tui.adoc | 13 +- .../dsl/jbang/core/commands/tui/ActionsPopup.java | 21 ++- .../dsl/jbang/core/commands/tui/CamelMonitor.java | 54 ++++++++ .../dsl/jbang/core/commands/tui/OverviewTab.java | 2 +- .../camel/dsl/jbang/core/commands/tui/Theme.java | 146 ++++++++++++++------- .../dsl/jbang/core/commands/tui/ThemeMode.java | 64 +++++++++ .../tui/ThemeModeCompletionCandidates.java | 28 ++++ .../dsl/jbang/core/commands/tui/TuiCommand.java | 9 ++ .../src/main/resources/tui/themes/dark.tcss | 28 ++-- .../src/main/resources/tui/themes/light.tcss | 28 ++-- .../jbang/core/commands/tui/CamelMonitorTest.java | 73 +++++++++++ .../dsl/jbang/core/commands/tui/ThemeTest.java | 71 +++++++--- 13 files changed, 443 insertions(+), 97 deletions(-) diff --cc dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/Theme.java index e3c666174523,7976f09a15a5..8bda7b090d81 --- a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/Theme.java +++ b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/Theme.java @@@ -246,13 -301,9 +304,10 @@@ final class Theme } try { StyleEngine e = StyleEngine.create(); - // Read CSS content via Theme's own classloader instead of delegating - // to StyleEngine.loadStylesheet() which uses StyleEngine.class.getClassLoader(). - // Under parallel test execution the two classloaders can diverge, causing - // intermittent "resource not found" failures in CI. - String cssContent = loadCssResource("tui/themes/" + mode + ".tcss"); - e.addStylesheet(mode, cssContent); - e.setActiveStylesheet(mode); + String stylesheet = mode.id(); - e.loadStylesheet(stylesheet, "tui/themes/" + stylesheet + ".tcss"); ++ String cssContent = loadCssResource("tui/themes/" + stylesheet + ".tcss"); ++ e.addStylesheet(stylesheet, cssContent); + e.setActiveStylesheet(stylesheet); engine = e; } catch (Exception ex) { engine = null; @@@ -261,41 -312,11 +316,36 @@@ return engine; } + /** + * Reads a CSS resource from the classpath using this class's own classloader, which in the normal Camel + * class-loading hierarchy has access to project resources. Falls back to the thread-context classloader when the + * primary lookup returns null (e.g., in OSGi or custom classloader setups) or when the class is bootstrap-loaded. + */ + private static String loadCssResource(String path) throws IOException { + InputStream is = null; + ClassLoader cl = Theme.class.getClassLoader(); + if (cl != null) { + is = cl.getResourceAsStream(path); + } + if (is == null) { - // Fallback to the thread context classloader in case the class's own classloader - // doesn't have visibility or is null (bootstrap-loaded classes). + ClassLoader tccl = Thread.currentThread().getContextClassLoader(); + if (tccl != null) { + is = tccl.getResourceAsStream(path); + } + } + if (is == null) { + throw new IOException("Theme CSS resource not found on classpath: " + path); + } + try (InputStream in = is) { + return new String(in.readAllBytes(), StandardCharsets.UTF_8); + } + } + - private static String loadPersistedMode() { - String[] holder = { DARK }; + private static ThemeMode loadPersistedMode() { + ThemeMode[] holder = { ThemeMode.DARK }; try { CommandLineHelper.loadProperties(props -> { - String v = props.getProperty(PROP_KEY); - if (DARK.equals(v) || LIGHT.equals(v)) { - holder[0] = v; - } + ThemeMode.parse(props.getProperty(PROP_KEY)).ifPresent(parsed -> holder[0] = parsed); }); } catch (RuntimeException ex) { // Config unreadable; keep the default mode.
