[
https://issues.apache.org/jira/browse/WW-5668?focusedWorklogId=1033303&page=com.atlassian.jira.plugin.system.issuetabpanels:worklog-tabpanel#worklog-1033303
]
ASF GitHub Bot logged work on WW-5668:
--------------------------------------
Author: ASF GitHub Bot
Created on: 01/Aug/26 08:18
Start Date: 01/Aug/26 08:18
Worklog Time Spent: 10m
Work Description: lukaszlenart opened a new pull request, #1824:
URL: https://github.com/apache/struts/pull/1824
Fixes [WW-5668](https://issues.apache.org/jira/browse/WW-5668)
Follow-up to #1821, which is already merged. Two defects in the
serialization handling that change shipped, both only observable when
deserializing a stream written by an **earlier** release — which is exactly
what a rolling upgrade does.
## 1. `serialVersionUID = 1L` breaks upgrades from 7.2.1
The localized-text providers are reachable from the `ValueStack` and really
are serialized — that is why #1821 had to make the caches `transient` in the
first place. Where a session is replicated or persisted, a 7.2.1 node's stream
can be read by a 7.3.0 node.
7.2.1 declared no explicit `serialVersionUID`, so its streams carry the
value the JVM computed from that class shape. Pinning `1L` does not match it,
and deserialization fails:
```
java.io.InvalidClassException:
org.apache.struts2.text.AbstractLocalizedTextProvider;
local class incompatible: stream classdesc serialVersionUID =
-4455624669971032217,
local class serialVersionUID = 1
```
This pins each provider to the value `serialver` reports for the
`STRUTS_7_2_1` tag instead:
| Class | Value |
| ---
Issue Time Tracking
-------------------
Worklog Id: (was: 1033303)
Time Spent: 1h 50m (was: 1h 40m)
> Make the localized-text provider caches size-bounded and align request-locale
> resolution across entry points
> ------------------------------------------------------------------------------------------------------------
>
> Key: WW-5668
> URL: https://issues.apache.org/jira/browse/WW-5668
> Project: Struts 2
> Issue Type: Improvement
> Reporter: Lukasz Lenart
> Assignee: Lukasz Lenart
> Priority: Major
> Fix For: 6.11.0, 7.3.0
>
> Time Spent: 1h 50m
> Remaining Estimate: 0h
>
> Two related follow-ups to the localized-text provider work in WW-5540.
> h2. 1. Bounded caches, consistent with the rest of the framework
> {{AbstractLocalizedTextProvider}} keeps several internal caches --
> {{bundlesMap}}, {{messageFormats}}, {{missingBundles}}, and the
> {{classHierarchyCache}} / {{packageHierarchyCache}} added in WW-5540. These
> are plain {{ConcurrentHashMap}}s with no configurable upper bound or eviction
> policy.
> Elsewhere the framework already standardises on bounded, configurable caches:
> the OGNL expression cache ({{struts.ognl.expressionCacheType=wtlfu}},
> {{struts.ognl.expressionCacheMaxSize=10000}}), the BeanInfo cache, and the
> proxy detection cache ({{struts.proxy.cacheMaxSize=10000}}) all support a
> cache type and a maximum size via {{OgnlCacheFactory}} /
> {{DefaultOgnlCacheFactory}}. The localized-text caches are the outlier.
> Bring them in line: give the localized-text caches a configurable maximum
> size and eviction (reusing the existing cache abstraction), with new
> constants following the established naming, e.g. {{struts.i18n.cacheType}}
> and {{struts.i18n.cacheMaxSize}}, defaulting to the same {{wtlfu}} /
> {{10000}} as the OGNL and proxy caches. Normal localized-text behaviour must
> be unchanged for typical applications.
> h2. 2. Consistent request-locale resolution
> Struts resolves a request locale from more than one place, and the two paths
> behave differently:
> * {{I18nInterceptor}} (the {{request_locale}} parameter / cookie / session
> path) resolves the value and then checks it against the available-locale set
> via {{LocaleProvider.isValidLocale(...)}}, falling back to the configured
> default when the resolved locale is not an available one.
> * {{Dispatcher.getLocale(...)}} -- used when {{struts.locale}} is unset --
> returns {{request.getLocale()}} directly, without that availability check.
> Align the two so a request-derived locale is resolved consistently regardless
> of entry point (a shared resolve/validate boundary, applying the same
> available-locale check the interceptor already uses).
> h2. Scope / acceptance
> * Localized-text caches honour a configurable maximum size with eviction;
> defaults match the existing OGNL/proxy cache conventions.
> * Request-locale resolution is consistent across {{Dispatcher}} and
> {{I18nInterceptor}}.
> * Documented in {{default.properties}} alongside the other cache settings.
> * Tests: cache size stays within the configured bound as locale/key diversity
> grows; correct localized text is still returned for normal and repeated
> locales; locale resolution behaviour is covered for both entry points.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)