This is an automated email from the ASF dual-hosted git repository. rmaucher pushed a commit to branch 9.0.x in repository https://gitbox.apache.org/repos/asf/tomcat.git
commit d7b3d932b275b28e16179179ce3b78c44138f781 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]
