This is an automated email from the ASF dual-hosted git repository. robertlazarski pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/axis-axis2-java-core.git
commit 905b30e4fd2efdc78c3dfa1e310f453e0839cc3d Author: Robert Lazarski <[email protected]> AuthorDate: Mon Apr 13 07:53:33 2026 -1000 AXIS2-5788 Add non-touching overload of getServiceGroupContext ConfigurationContext.getServiceGroupContext(id) always calls ServiceGroupContext.touch() on a hit, which resets lastTouchedTime. That is an "observer effect": any caller that wants to inspect a context (e.g. a session-cleanup sweep evaluating staleness against lastTouchedTime) mutates the very field it is trying to read and ends up keeping the context alive forever. Add an overload that takes an explicit touchServiceGroupContext flag: ServiceGroupContext getServiceGroupContext(String id, boolean touchServiceGroupContext) The existing single-arg method is preserved and delegates with touch=true, so legacy callers see no behaviour change. Callers that want a read-only peek pass touch=false. Also fix the stale Javadoc on getServiceGroupContextIDs() noted in the same ticket (it claimed to return a hashmap; it returns a String[]). No functional change to the lookup itself beyond collapsing the duplicated touch() call at the two hit sites into a single branch. --- .../apache/axis2/context/ConfigurationContext.java | 49 +++++++++++++++++----- 1 file changed, 38 insertions(+), 11 deletions(-) diff --git a/modules/kernel/src/org/apache/axis2/context/ConfigurationContext.java b/modules/kernel/src/org/apache/axis2/context/ConfigurationContext.java index 69ebc4eb8a..1365a582f0 100644 --- a/modules/kernel/src/org/apache/axis2/context/ConfigurationContext.java +++ b/modules/kernel/src/org/apache/axis2/context/ConfigurationContext.java @@ -500,12 +500,36 @@ public class ConfigurationContext extends AbstractContext { /** * Returns a ServiceGroupContext object associated with the specified ID from the internal - * table. + * table. The returned context's {@code lastTouchedTime} is updated as a side effect of the + * lookup; use {@link #getServiceGroupContext(String, boolean)} with {@code touch=false} + * if the caller needs to inspect the context (for example to evaluate staleness against + * {@code lastTouchedTime}) without mutating it. See AXIS2-5788. * * @param serviceGroupCtxId The ID string associated with the ServiceGroupContext object * @return The ServiceGroupContext object, or null if not found */ public ServiceGroupContext getServiceGroupContext(String serviceGroupCtxId) { + return getServiceGroupContext(serviceGroupCtxId, true); + } + + /** + * Returns a ServiceGroupContext object associated with the specified ID from the internal + * table, optionally updating its {@code lastTouchedTime}. + * <p> + * Passing {@code touchServiceGroupContext=false} lets external code read the context + * without the "observer effect" described in + * <a href="https://issues.apache.org/jira/browse/AXIS2-5788">AXIS2-5788</a>: + * for example, session-cleanup code that wants to evaluate staleness against + * {@code lastTouchedTime} would otherwise reset the clock by the very act of looking. + * + * @param serviceGroupCtxId The ID string associated with the ServiceGroupContext object. + * @param touchServiceGroupContext {@code true} to update {@code lastTouchedTime} on a hit + * (legacy behaviour preserved for back-compat), {@code false} + * to leave it unchanged. + * @return The ServiceGroupContext object, or null if not found. + */ + public ServiceGroupContext getServiceGroupContext(String serviceGroupCtxId, + boolean touchServiceGroupContext) { if (serviceGroupCtxId == null) { // Hashtables require non-null key-value pairs @@ -515,15 +539,13 @@ public class ConfigurationContext extends AbstractContext { ServiceGroupContext serviceGroupContext = null; if (serviceGroupContextMap != null) { - serviceGroupContext =serviceGroupContextMap.get(serviceGroupCtxId); - if (serviceGroupContext != null) { - serviceGroupContext.touch(); - } else { - serviceGroupContext =applicationSessionServiceGroupContexts + serviceGroupContext = serviceGroupContextMap.get(serviceGroupCtxId); + if (serviceGroupContext == null) { + serviceGroupContext = applicationSessionServiceGroupContexts .get(serviceGroupCtxId); - if (serviceGroupContext != null) { - serviceGroupContext.touch(); - } + } + if (serviceGroupContext != null && touchServiceGroupContext) { + serviceGroupContext.touch(); } } @@ -532,9 +554,14 @@ public class ConfigurationContext extends AbstractContext { } /** - * Gets all service groups in the system. + * Returns the IDs of all service groups currently held by this + * {@code ConfigurationContext} (both SOAP-session and application-session scoped). + * <p> + * Fixes the stale Javadoc noted in + * <a href="https://issues.apache.org/jira/browse/AXIS2-5788">AXIS2-5788</a>: the return + * type is a {@code String[]}, not a hashmap of {@code ServiceGroupContext} instances. * - * @return Returns hashmap of ServiceGroupContexts. + * @return an array of service group context IDs; never {@code null}, but may be empty. */ public String[] getServiceGroupContextIDs() { String[] ids = new String[serviceGroupContextMap.size() +
