This is an automated email from the ASF dual-hosted git repository. rmaucher pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/tomcat.git
commit 2688684cc54b7bd5921e74d0ae9a9847fccccde6 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 8f67f06382..e3ef492d3d 100644 --- a/java/org/apache/catalina/ha/tcp/SimpleTcpCluster.java +++ b/java/org/apache/catalina/ha/tcp/SimpleTcpCluster.java @@ -690,7 +690,6 @@ public class SimpleTcpCluster extends LifecycleMBeanBase setState(LifecycleState.STOPPING); - unregisterMember(channel.getLocalMember(false)); if (clusterDeployer != null) { clusterDeployer.stop(); } @@ -699,13 +698,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]
