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

Croway pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git


The following commit(s) were added to refs/heads/main by this push:
     new 320d67b5c05d CAMEL-25197: camel-cli-connector - do not keep the JVM 
running after the stop action
320d67b5c05d is described below

commit 320d67b5c05de8c03ed39de2513814b739a5eb9d
Author: croway <[email protected]>
AuthorDate: Thu Oct 1 15:56:56 2026 +0200

    CAMEL-25197: camel-cli-connector - do not keep the JVM running after the 
stop action
    
    LocalCliConnector.sigterm() runs the termination on a single thread 
executor that was never
    shut down: its non-daemon thread kept waiting for more tasks once Camel was 
stopped, so a
    Spring Boot application did not exit after the stop action (camel stop, or 
the websocket
    transport). Camel Main exits anyway, which hid it. Shut the executor down 
after submitting
    the task, so the thread ends once the task is done.
    
    Co-Authored-By: Claude Opus 5.5 <[email protected]>
---
 .../camel/cli/connector/LocalCliConnector.java     |  3 ++
 .../connector/LocalCliConnectorSigtermTest.java    | 56 ++++++++++++++++++++++
 2 files changed, 59 insertions(+)

diff --git 
a/dsl/camel-cli-connector/src/main/java/org/apache/camel/cli/connector/LocalCliConnector.java
 
b/dsl/camel-cli-connector/src/main/java/org/apache/camel/cli/connector/LocalCliConnector.java
index 5468974c3f79..ec9645068cb3 100644
--- 
a/dsl/camel-cli-connector/src/main/java/org/apache/camel/cli/connector/LocalCliConnector.java
+++ 
b/dsl/camel-cli-connector/src/main/java/org/apache/camel/cli/connector/LocalCliConnector.java
@@ -226,6 +226,9 @@ public class LocalCliConnector extends ServiceSupport
                 }
             }
         });
+        // the thread ends once the task is done: a non-daemon thread left 
waiting for more tasks keeps the JVM
+        // running (Spring Boot)
+        terminateExecutor.shutdown();
     }
 
     @Override
diff --git 
a/dsl/camel-cli-connector/src/test/java/org/apache/camel/cli/connector/LocalCliConnectorSigtermTest.java
 
b/dsl/camel-cli-connector/src/test/java/org/apache/camel/cli/connector/LocalCliConnectorSigtermTest.java
new file mode 100644
index 000000000000..a8193f9b4f69
--- /dev/null
+++ 
b/dsl/camel-cli-connector/src/test/java/org/apache/camel/cli/connector/LocalCliConnectorSigtermTest.java
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.cli.connector;
+
+import java.util.concurrent.TimeUnit;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.ServiceStatus;
+import org.apache.camel.spi.CliConnectorFactory;
+import org.apache.camel.test.junit6.CamelTestSupport;
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.awaitility.Awaitility.await;
+
+class LocalCliConnectorSigtermTest extends CamelTestSupport {
+
+    @Override
+    protected CamelContext createCamelContext() throws Exception {
+        CamelContext context = super.createCamelContext();
+        // do not let the context start the connector found on the classpath, 
the test uses its own
+        DefaultCliConnectorFactory disabled = new DefaultCliConnectorFactory();
+        disabled.setEnabled(false);
+        
context.getCamelContextExtension().addContextPlugin(CliConnectorFactory.class, 
disabled);
+        return context;
+    }
+
+    @Test
+    void terminateThreadEndsOnceCamelIsStopped() {
+        LocalCliConnector connector = new LocalCliConnector(new 
DefaultCliConnectorFactory());
+        connector.setCamelContext(context);
+
+        connector.sigterm();
+
+        await().atMost(20, TimeUnit.SECONDS).untilAsserted(() -> {
+            assertThat(context.getStatus()).isEqualTo(ServiceStatus.Stopped);
+            // a non-daemon thread left behind keeps the JVM running (Spring 
Boot)
+            assertThat(Thread.getAllStackTraces().keySet())
+                    .noneMatch(t -> t.getName().endsWith("Terminate JVM task") 
&& t.isAlive());
+        });
+    }
+}

Reply via email to