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

rmaucher pushed a commit to branch 10.1.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git

commit 6521777344f17544b9db98e1fe4c10352925de00
Author: opencode <[email protected]>
AuthorDate: Wed Sep 30 23:11:22 2026 +0200

    Make SimpleTcpCluster.stopInternal() cleanup robust: guard each step so a 
channel stop failure cannot skip listener removal and cluster valve 
unregistration, and unregister the MBeans of all cluster members from the 
member name map on stop
---
 .../apache/catalina/ha/tcp/SimpleTcpCluster.java   | 24 ++++++++++++++++++++--
 1 file changed, 22 insertions(+), 2 deletions(-)

diff --git a/java/org/apache/catalina/ha/tcp/SimpleTcpCluster.java 
b/java/org/apache/catalina/ha/tcp/SimpleTcpCluster.java
index 7f1f0de2ad..4150f9054b 100644
--- a/java/org/apache/catalina/ha/tcp/SimpleTcpCluster.java
+++ b/java/org/apache/catalina/ha/tcp/SimpleTcpCluster.java
@@ -692,7 +692,6 @@ public class SimpleTcpCluster extends LifecycleMBeanBase
 
         setState(LifecycleState.STOPPING);
 
-        unregisterMember(channel.getLocalMember(false));
         if (clusterDeployer != null) {
             clusterDeployer.stop();
         }
@@ -701,13 +700,34 @@ public class SimpleTcpCluster extends LifecycleMBeanBase
             if (clusterDeployer != null) {
                 clusterDeployer.setCluster(null);
             }
+        } catch (Exception e) {
+            log.error(sm.getString("simpleTcpCluster.stopUnable"), e);
+        }
+        try {
             channel.stop(channelStartOptions);
+        } catch (Exception e) {
+            log.error(sm.getString("simpleTcpCluster.stopUnable"), e);
+        }
+        // These steps must also run when stopping the channel failed,
+        // otherwise the cluster valves remain in the container pipeline and
+        // would be linked a second time on the next start
+        try {
             channel.removeChannelListener(this);
             channel.removeMembershipListener(this);
-            this.unregisterClusterValve();
         } catch (Exception e) {
             log.error(sm.getString("simpleTcpCluster.stopUnable"), e);
         }
+        try {
+            unregisterClusterValve();
+        } catch (Exception e) {
+            log.error(sm.getString("simpleTcpCluster.stopUnable"), e);
+        }
+        // Unregister the MBeans of the local member and of any remote members
+        // for which memberDisappeared() did not fire during the stop
+        for (ObjectName oname : memberOnameMap.values()) {
+            unregister(oname);
+        }
+        memberOnameMap.clear();
 
         channel.setUtilityExecutor(null);
     }


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to