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 f1178f87a369e750e70bda10e6fac84279c77f01 Author: opencode <[email protected]> AuthorDate: Tue Oct 13 09:11:02 2026 +0200 Avoid caching unregistered upgrade group infos The map of upgrade protocol name to UpgradeGroupInfo was populated before the attempt to register the group info with JMX. When that registration failed, only the local reference was nulled and the never registered instance remained cached, so every later upgrade for the protocol silently used an instance exposed by no MBean and the registration was never retried. The cached instances also survived destroy(), which had de-registered the upgrade MBeans, preventing any re-registration if the handler was later re-initialised. Restructure the lazy initialisation to only cache the group info once it is usable: registered with JMX when an ObjectName is available, or unconditionally when JMX registration is not possible, preserving the existing behaviour in that case. A failed registration now returns null to the caller, as it did before, and allows a later call to retry. In destroy(), clear the cached group infos under the monitor that guards their creation and registration so they are released and, if the handler is re-initialised, re-created and registered with JMX. --- .../coyote/http11/AbstractHttp11Protocol.java | 36 +++++++++++++++------- 1 file changed, 25 insertions(+), 11 deletions(-) diff --git a/java/org/apache/coyote/http11/AbstractHttp11Protocol.java b/java/org/apache/coyote/http11/AbstractHttp11Protocol.java index ca23f99175..b7ec72c203 100644 --- a/java/org/apache/coyote/http11/AbstractHttp11Protocol.java +++ b/java/org/apache/coyote/http11/AbstractHttp11Protocol.java @@ -107,16 +107,24 @@ public abstract class AbstractHttp11Protocol<S> extends AbstractProtocol<S> { @Override public void destroy() throws Exception { - // There may be upgrade protocols with their own MBeans. These need to - // be de-registered. - ObjectName rgOname = getGlobalRequestProcessorMBeanName(); - if (rgOname != null) { - Registry registry = Registry.getRegistry(null); - ObjectName query = new ObjectName(rgOname.getCanonicalName() + ",Upgrade=*"); - Set<ObjectInstance> upgrades = registry.getMBeanServer().queryMBeans(query, null); - for (ObjectInstance upgrade : upgrades) { - registry.unregisterComponent(upgrade.getObjectName()); + // Synchronise on the group info map to prevent an upgrade that is + // being created and registered from racing with the de-registration + // below and the clearing of the map. + synchronized (upgradeProtocolGroupInfos) { + // There may be upgrade protocols with their own MBeans. These need + // to be de-registered. + ObjectName rgOname = getGlobalRequestProcessorMBeanName(); + if (rgOname != null) { + Registry registry = Registry.getRegistry(null); + ObjectName query = new ObjectName(rgOname.getCanonicalName() + ",Upgrade=*"); + Set<ObjectInstance> upgrades = registry.getMBeanServer().queryMBeans(query, null); + for (ObjectInstance upgrade : upgrades) { + registry.unregisterComponent(upgrade.getObjectName()); + } } + // Release the cached group infos so they are freed and, if the + // handler is re-initialised, re-created and registered with JMX. + upgradeProtocolGroupInfos.clear(); } super.destroy(); @@ -909,7 +917,9 @@ public abstract class AbstractHttp11Protocol<S> extends AbstractProtocol<S> { * Get the upgrade group info for the specified upgrade protocol. * * @param upgradeProtocol The upgrade protocol name - * @return The upgrade group info for the specified protocol + * @return The upgrade group info for the specified protocol, or + * {@code null} if the protocol name is null or the statistics + * MBean for the protocol could not be registered */ public UpgradeGroupInfo getUpgradeGroupInfo(String upgradeProtocol) { if (upgradeProtocol == null) { @@ -923,16 +933,20 @@ public abstract class AbstractHttp11Protocol<S> extends AbstractProtocol<S> { result = upgradeProtocolGroupInfos.get(upgradeProtocol); if (result == null) { result = new UpgradeGroupInfo(); - upgradeProtocolGroupInfos.put(upgradeProtocol, result); ObjectName oname = getONameForUpgrade(upgradeProtocol); if (oname != null) { try { Registry.getRegistry(null).registerComponent(result, oname, null); } catch (Exception e) { getLog().warn(sm.getString("abstractHttp11Protocol.upgradeJmxRegistrationFail"), e); + // Do not cache the result so that a later call can + // retry the registration. result = null; } } + if (result != null) { + upgradeProtocolGroupInfos.put(upgradeProtocol, result); + } } } } --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
