You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2026/10/01 15:49:51 UTC

(camel) 01/01: CAMEL-25230: camel-cli-connector - the connector thread keeps the JVM alive when the application fails to start

This is an automated email from the ASF dual-hosted git repository.

davsclaus pushed a commit to branch fix/CAMEL-25230
in repository https://gitbox.apache.org/repos/asf/camel.git

commit bf7e4dd77242df581feb742759d666e9309a00c5
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Thu Oct 1 16:01:13 2026 +0200

    CAMEL-25230: camel-cli-connector - the connector thread keeps the JVM alive when the application fails to start
    
    Co-Authored-By: Claude Opus 5.5 (1M context) <no...@anthropic.com>
    Signed-off-by: Claus Ibsen <cl...@gmail.com>
---
 .../modules/ROOT/pages/camel-4x-upgrade-guide-4_23.adoc   |  6 ++++++
 .../camel/cli/connector/FileCliConnectorTransport.java    |  8 ++++++--
 .../cli/connector/LocalCliConnectorFileTransportTest.java | 15 +++++++++++++++
 3 files changed, 27 insertions(+), 2 deletions(-)

diff --git a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_23.adoc b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_23.adoc
index c506d4e1fe6e..84a3776b0714 100644
--- a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_23.adoc
+++ b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_23.adoc
@@ -4097,3 +4097,9 @@ only just modified for the next scan, so a save still being written is not reloa
 The ~/.camel file handling moved from `LocalCliConnector` to the new `FileCliConnectorTransport`, so the protected
 `task()`, `actionTask()`, `statusTask()` and `traceTask()` methods were removed from `LocalCliConnector`. Subclasses
 that only override `sigterm()` are not affected.
+
+The thread of the file transport (`LocalCliConnector` in its name) is now a daemon thread, as the threads of the
+WebSocket transport already were. Before, it kept the JVM alive when the application failed to start, for example a
+Spring Boot application whose port was in use: Camel had not started, so it never stopped the connector. An application
+that only kept running because of this thread now exits; keep it running on purpose, for example with
+`camel.main.run-controller=true` for a Spring Boot application without a web server.
diff --git a/dsl/camel-cli-connector/src/main/java/org/apache/camel/cli/connector/FileCliConnectorTransport.java b/dsl/camel-cli-connector/src/main/java/org/apache/camel/cli/connector/FileCliConnectorTransport.java
index c5e1a3aec8f2..7d51bc62a059 100644
--- a/dsl/camel-cli-connector/src/main/java/org/apache/camel/cli/connector/FileCliConnectorTransport.java
+++ b/dsl/camel-cli-connector/src/main/java/org/apache/camel/cli/connector/FileCliConnectorTransport.java
@@ -82,10 +82,14 @@ public class FileCliConnectorTransport extends ServiceSupport implements CliConn
         terminating.set(false);
 
         // create thread from JDK so it is not managed by Camel because we want the pool to be independent when
-        // camel is being stopped which otherwise can lead to stopping the thread pool while the task is running
+        // camel is being stopped which otherwise can lead to stopping the thread pool while the task is running.
+        // a daemon thread: the connector starts before Camel, so when the application fails to start (Spring Boot
+        // APPLICATION FAILED TO START) Camel never stops it, and it must not keep the JVM alive (CAMEL-25230)
         executor = Executors.newSingleThreadScheduledExecutor(r -> {
             String threadName = ThreadHelper.resolveThreadName(null, "LocalCliConnector");
-            return new Thread(r, threadName);
+            Thread thread = new Thread(r, threadName);
+            thread.setDaemon(true);
+            return thread;
         });
 
         // make it go faster in debug mode
diff --git a/dsl/camel-cli-connector/src/test/java/org/apache/camel/cli/connector/LocalCliConnectorFileTransportTest.java b/dsl/camel-cli-connector/src/test/java/org/apache/camel/cli/connector/LocalCliConnectorFileTransportTest.java
index f5ff11126751..81d387323037 100644
--- a/dsl/camel-cli-connector/src/test/java/org/apache/camel/cli/connector/LocalCliConnectorFileTransportTest.java
+++ b/dsl/camel-cli-connector/src/test/java/org/apache/camel/cli/connector/LocalCliConnectorFileTransportTest.java
@@ -120,6 +120,21 @@ class LocalCliConnectorFileTransportTest extends CamelTestSupport {
         }
     }
 
+    @Test
+    void theConnectorDoesNotKeepTheJvmAlive() throws Exception {
+        // started before Camel, it is not stopped when the application fails to start (CAMEL-25230). Started from a
+        // non-daemon thread, as the main thread of Spring Boot: a new thread takes the daemon flag of its creator
+        Thread main = new Thread(this::startConnector, "main");
+        main.setDaemon(false);
+        main.start();
+        main.join(10_000);
+
+        await().atMost(10, TimeUnit.SECONDS).untilAsserted(() -> assertThat(Thread.getAllStackTraces().keySet())
+                .filteredOn(t -> t.getName().contains("LocalCliConnector"))
+                .isNotEmpty()
+                .allMatch(Thread::isDaemon));
+    }
+
     @Test
     void writesStatusSnapshot() {
         startConnector();