lukaszlenart opened a new pull request, #1823:
URL: https://github.com/apache/struts/pull/1823

   Fixes [WW-5668](https://issues.apache.org/jira/browse/WW-5668)
   
   Backport of #1821 to the 6.x maintenance line, targeting 6.11.0. Two 
related, independent changes to the localized-text subsystem.
   
   ## 1. Bounded localized-text caches
   
   `AbstractLocalizedTextProvider` kept its internal caches (`bundlesMap`, 
`messageFormats`, `missingBundles`) as plain `ConcurrentHashMap`s with no 
configurable upper bound or eviction. The rest of the framework already 
standardises on bounded caches via `OgnlCacheFactory` 
(`struts.ognl.expressionCacheMaxSize`, `struts.ognl.beanInfoCacheMaxSize`, both 
`wtlfu`); these were the outlier.
   
   - Reuse the existing `OgnlCache` abstraction (`DefaultOgnlCacheFactory`) for 
all three caches, with configurable size and eviction.
   - New constants `struts.i18n.cacheType` (default `wtlfu`) and 
`struts.i18n.cacheMaxSize` (default `10000`), documented in 
`default.properties`.
   - Added `remove(key)` to `OgnlCache` (needed by `clearBundle`).
   - Caches are `transient` and rebuilt in `readObject` so the provider stays 
serializable; a dedicated lock replaces synchronizing on the now-reassignable 
`bundlesMap`.
   
   All three caches are pure/reconstructible, so eviction can only cause a 
recompute, never a wrong or stale localized result.
   
   ## 2. Consistent request-locale resolution (opt-in)
   
   `I18nInterceptor` validates a resolved locale against the available-locale 
set (`LocaleProvider.isValidLocale`), but `Dispatcher.getLocale(...)` (used 
when `struts.locale` is unset) returns `request.getLocale()` directly without 
that check.
   
   - New `struts.locale.validateRequestLocale` (default `false` — current 
behaviour preserved byte-for-byte). When enabled, `Dispatcher` resolves 
request-derived locales against the JVM available-locale set, falling back to 
the configured `struts.locale` (else the JVM default), consistent with 
`I18nInterceptor`.
   
   ## Differences from #1821
   
   - 6.x has three of these caches, not five — `classHierarchyCache` / 
`packageHierarchyCache` were added by WW-5540, which is `main`-only.
   - Classes live under `com.opensymphony.xwork2.*` (pre-XWork-merge layout), 
so this is a manual re-apply rather than a cherry-pick.
   - `missingBundles` moves from `Set<String>` to `OgnlCache<String, Boolean>`, 
and the `bundlesMap.containsKey` double-checks become `get(key) != null`, since 
`OgnlCache` exposes neither.
   - `CacheFixture` (test fixture + bundle) is added here; on `main` it arrived 
with WW-5540.
   
   Note `AbstractLocalizedTextProvider` is package-private, so the type change 
on the `protected bundlesMap` field is not reachable outside 
`com.opensymphony.xwork2.util` and breaks no public API.
   
   ## Testing
   
   - New tests: cache bound invariant, correctness under eviction, reload 
clears, serialize→deserialize→`findText`, cache-type selection, and the three 
`Dispatcher` flag states (off / on-available / on-fallback).
   - Full `core` suite green: 2711 tests, 0 failures, 0 errors.
   
   ## Backward compatibility
   
   - Part 1 changes internal cache implementations only; eviction is 
correctness-safe; defaults match existing cache conventions.
   - Part 2 is fully opt-in and defaults off.
   
   🤖 Generated with [Claude Code](https://claude.com/claude-code)
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to