lukaszlenart opened a new pull request, #1808: URL: https://github.com/apache/struts/pull/1808
Fixes [WW-5540](https://issues.apache.org/jira/browse/WW-5540) ## What Caches the class- and package-hierarchy traversal performed by `StrutsLocalizedTextProvider.findText(Class, …)`, so repeated lookups for the same `(classloader, class name, key, locale)` collapse to a single `ConcurrentHashMap` lookup instead of re-walking the class → interface → superclass → `*.package` hierarchy on every call. This path backs every UI tag label and validation message rendered per request; missing keys were especially costly (full hierarchy walk + swallowed `MissingResourceException` per level, repeated every request). ## How - **Raw / format split** — resolution of the raw message pattern is separated from rendering. Only the **raw pattern** (or a `NOT_FOUND` identity sentinel) is cached; OGNL `translateVariables` and `MessageFormat` argument substitution still run **per call**, so dynamic `${…}` messages and per-call args remain correct. - **Two caches** in `AbstractLocalizedTextProvider` (`classHierarchyCache`, `packageHierarchyCache`), keyed on the classloader hash + **class name (String)** — never a `Class` object, so no classloader pinning. - **Invalidation** wired into `reloadBundles`, `clearBundle`, and `clearMissingBundlesCache`; the reload check is hoisted to the top of `findText` so devMode/`struts.i18n.reload=true` clears the caches before they are read. - `getMessage` / `findMessage` are retained as `@Deprecated` delegators for descendant classes. ## Behavior Behavior-preserving: lookup order, dynamic-message evaluation, argument formatting, and devMode/reload semantics are unchanged. The one documented, accepted divergence is a pathological case where the same key is redefined at multiple levels of a single class hierarchy and the shallowest match formats to the literal string `"null"`. Caches are unbounded, consistent with the existing `bundlesMap` / `missingBundles`. See the design spec under `docs/superpowers/specs/` for details. ## Testing `mvn test -DskipAssembly -pl core -Dtest=StrutsLocalizedTextProviderTest` → 33/33 green (11 new tests covering raw-only caching, per-call formatting/OGNL, miss caching, the null-format fall-through, and cache invalidation at all three clear sites). Broader localized-text slice: 54/54 green. ## Follow-up A separate, deferred cleanup (replacing the `null`-overloaded control flow with an explicit result type) is drafted under `docs/superpowers/followups/` and not yet filed. 🤖 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]
