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]
