[
https://issues.apache.org/jira/browse/WW-5540?focusedWorklogId=1031830&page=com.atlassian.jira.plugin.system.issuetabpanels:worklog-tabpanel#worklog-1031830
]
ASF GitHub Bot logged work on WW-5540:
--------------------------------------
Author: ASF GitHub Bot
Created on: 23/Jul/26 11:42
Start Date: 23/Jul/26 11:42
Worklog Time Spent: 10m
Work Description: 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)
Issue Time Tracking
-------------------
Worklog Id: (was: 1031830)
Remaining Estimate: 0h
Time Spent: 10m
> Add caching to AbstractLocalizedTextProvider
> --------------------------------------------
>
> Key: WW-5540
> URL: https://issues.apache.org/jira/browse/WW-5540
> Project: Struts 2
> Issue Type: Improvement
> Components: Core
> Affects Versions: 6.7.4, 7.0.3
> Reporter: Kusal Kithul-Godage
> Assignee: Lukasz Lenart
> Priority: Minor
> Fix For: 7.3.0
>
> Time Spent: 10m
> Remaining Estimate: 0h
>
> Performance enhancement
--
This message was sent by Atlassian Jira
(v8.20.10#820010)