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 <[email protected]>
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) <[email protected]>
    Signed-off-by: Claus Ibsen <[email protected]>
---
 .../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();

Reply via email to