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 7a750eba7425833ccb6cfb2a7dfc2eb93deee63d Author: opencode <[email protected]> AuthorDate: Wed Sep 30 22:46:43 2026 +0200 Move attributes set during web application startup into the replicated attribute map when it is installed in ReplicatedContext so they are replicated to the other nodes --- .../catalina/ha/context/ReplicatedContext.java | 21 +++++++++++++++++++-- webapps/docs/changelog.xml | 7 +++++++ 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/java/org/apache/catalina/ha/context/ReplicatedContext.java b/java/org/apache/catalina/ha/context/ReplicatedContext.java index ccedb5facc..2dd2e06bc0 100644 --- a/java/org/apache/catalina/ha/context/ReplicatedContext.java +++ b/java/org/apache/catalina/ha/context/ReplicatedContext.java @@ -169,6 +169,12 @@ public class ReplicatedContext extends StandardContext implements MapOwner { * Application context implementation for replicated contexts. */ protected static class ReplApplContext extends ApplicationContext { + /** + * Attribute name used by Jasper for its application context. It holds + * node specific state and must therefore never be replicated. + */ + private static final String JSP_APP_CONTEXT_NAME = "org.apache.jasper.runtime.JspApplicationContextImpl"; + /** * Map for Tomcat-specific attributes that should not be replicated. */ @@ -213,6 +219,18 @@ public class ReplicatedContext extends StandardContext implements MapOwner { */ public void setAttributeMap(Map<String,Object> map) { this.attributes = map; + // Attributes set while the context was starting were stored in the + // local map. Move them to the new map so that they are handled the + // same way as attributes set later on, in particular replicated to + // the other nodes. Values that cannot be serialized are stored + // locally by the replicated map. + for (Map.Entry<String,Object> entry : tomcatAttributes.entrySet()) { + if (JSP_APP_CONTEXT_NAME.equals(entry.getKey())) { + continue; + } + map.put(entry.getKey(), entry.getValue()); + tomcatAttributes.remove(entry.getKey()); + } } @Override @@ -230,8 +248,7 @@ public class ReplicatedContext extends StandardContext implements MapOwner { removeAttribute(name); return; } - if ((!getParent().getState().isAvailable()) || - "org.apache.jasper.runtime.JspApplicationContextImpl".equals(name)) { + if ((!getParent().getState().isAvailable()) || JSP_APP_CONTEXT_NAME.equals(name)) { tomcatAttributes.put(name, value); } else { super.setAttribute(name, value); diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml index 2a649365d3..cb15097a1f 100644 --- a/webapps/docs/changelog.xml +++ b/webapps/docs/changelog.xml @@ -181,6 +181,13 @@ the last associated session expires, even when the sessions expire on different cluster nodes. (remm) </fix> + <fix> + Move context attributes that were set while the web application was + still starting into the replicated attribute map when it is installed + in <code>ReplicatedContext</code>, so that they are replicated to the + other nodes like attributes set later on rather than remaining local to + the node that started the application. (remm) + </fix> </changelog> </subsection> <subsection name="Web applications"> --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
