[ 
https://issues.apache.org/jira/browse/WW-5540?focusedWorklogId=1031850&page=com.atlassian.jira.plugin.system.issuetabpanels:worklog-tabpanel#worklog-1031850
 ]

ASF GitHub Bot logged work on WW-5540:
--------------------------------------

                Author: ASF GitHub Bot
            Created on: 23/Jul/26 12:27
            Start Date: 23/Jul/26 12:27
    Worklog Time Spent: 10m 
      Work Description: lukaszlenart commented on code in PR #1808:
URL: https://github.com/apache/struts/pull/1808#discussion_r3638055400


##########
core/src/main/java/org/apache/struts2/text/StrutsLocalizedTextProvider.java:
##########
@@ -65,6 +65,11 @@ public String findText(Class<?> startClazz, String textKey, 
Locale locale, Strin
             LOG.debug("Key is null, short-circuit to default message");
             return defaultMessage;
         }
+
+        // Trigger bundle reload (and cache invalidation) once, before any 
cached hierarchy lookup,
+        // so that in reload/devMode the hierarchy caches are cleared before 
they are read.
+        reloadBundles(valueStack != null ? valueStack.getContext() : null);

Review Comment:
   Good catch — this was also flagged by an internal review pass and fixed in 
e4166f876 (before this comment was posted): when the value stack is null, 
`findText` now falls back to the ActionContext-based `reloadBundles()` 
overload, so the `RELOADED` flag is tracked and the caches can warm on that 
path.



##########
core/src/main/java/org/apache/struts2/text/AbstractLocalizedTextProvider.java:
##########
@@ -90,6 +93,20 @@ protected ClassLoader getCurrentThreadContextClassLoader() {
         return Thread.currentThread().getContextClassLoader();
     }
 
+    private int currentLoaderHashCode() {
+        return getCurrentThreadContextClassLoader().hashCode();
+    }

Review Comment:
   Fixed in b04e0f416 — `currentLoaderHashCode()` now uses 
`System.identityHashCode(...)`. The pre-existing maps (`classLoaderMap`, 
`createMissesKey`) keep their `hashCode()`-based keying for now; the new caches 
don't share keys with them, so the divergence is safe.



##########
core/src/main/java/org/apache/struts2/text/AbstractLocalizedTextProvider.java:
##########
@@ -582,23 +628,113 @@ protected String findMessage(Class<?> clazz, String key, 
String indexedKey, Loca
         // traverse up hierarchy
         if (clazz.isInterface()) {
             interfaces = clazz.getInterfaces();
-
             for (Class<?> anInterface : interfaces) {
-                msg = findMessage(anInterface, key, indexedKey, locale, args, 
checked, valueStack);
-
+                msg = findMessageRaw(anInterface, key, indexedKey, locale, 
checked);
                 if (msg != null) {
                     return msg;
                 }
             }
         } else {
             if (!clazz.equals(Object.class) && !clazz.isPrimitive()) {
-                return findMessage(clazz.getSuperclass(), key, indexedKey, 
locale, args, checked, valueStack);
+                return findMessageRaw(clazz.getSuperclass(), key, indexedKey, 
locale, checked);
             }
         }
 
         return null;
     }
 
+    /**
+     * Cached resolution of the class/interface/superclass hierarchy for a 
key. Returns the raw pattern
+     * found, or {@link #NOT_FOUND} when the key is absent from the entire 
hierarchy. Keyed on the
+     * context classloader hash + class name + key + locale, so no {@link 
Class} reference is retained.
+     * Uses get + putIfAbsent (never computeIfAbsent) because the 
child-property path recurses into findText.
+     */
+    protected String resolveClassHierarchyRaw(Class<?> clazz, String textKey, 
String indexedKey, Locale locale) {
+        TextCacheKey cacheKey = new TextCacheKey(currentLoaderHashCode(), 
clazz.getName(), textKey, locale);
+        String cached = classHierarchyCache.get(cacheKey);

Review Comment:
   Fixed in b04e0f416 using the stronger variant you suggested: the 
`indexedKey` parameter was removed and the resolvers derive it internally via 
`extractIndexedName(textKey)` (miss-only), so the cache key now covers every 
input that influences the resolution result.





Issue Time Tracking
-------------------

    Worklog Id:     (was: 1031850)
    Time Spent: 1h 20m  (was: 1h 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: 1h 20m
>  Remaining Estimate: 0h
>
> Performance enhancement



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to