This is an automated email from the ASF dual-hosted git repository.

lukaszlenart pushed a commit to branch WW-3530-visitor-validator-cache-key
in repository https://gitbox.apache.org/repos/asf/struts.git

commit f23b2eb879ccdb6bc8b188c29f10c58ae307e3d1
Author: Lukasz Lenart <[email protected]>
AuthorDate: Sat Jul 25 09:16:51 2026 +0200

    WW-3530 fix(core): keep visitor-validator context in cache key under 
wildcard actions
    
    Apply the wildcard config-name substitution only when validating the 
action's
    own class. Visited objects carry a stable, explicit visitor context that 
must
    remain part of the cache key, otherwise two visitor validators on one field 
with
    different contexts collide and the second is silently dropped.
    
    Fixes https://issues.apache.org/jira/browse/WW-3530
    
    Co-Authored-By: Claude Opus 4.8 <[email protected]>
---
 .../struts2/validator/AnnotationActionValidatorManager.java  | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git 
a/core/src/main/java/org/apache/struts2/validator/AnnotationActionValidatorManager.java
 
b/core/src/main/java/org/apache/struts2/validator/AnnotationActionValidatorManager.java
index c2d5ca1e1..b065202e5 100644
--- 
a/core/src/main/java/org/apache/struts2/validator/AnnotationActionValidatorManager.java
+++ 
b/core/src/main/java/org/apache/struts2/validator/AnnotationActionValidatorManager.java
@@ -48,13 +48,21 @@ public class AnnotationActionValidatorManager extends 
DefaultActionValidatorMana
             sb.append(config.getPackageName());
             sb.append("/");
         }
+
+        Object action = invocation.getAction();
+        boolean validatingActionClass = action != null && 
clazz.equals(action.getClass());
+        String configName = config.getName();
+        boolean wildcard = configName.contains(ActionConfig.WILDCARD)
+                || (configName.contains("{") && configName.contains("}"));
+
         // WW-2996: key needs to use the name of the action from the config 
file, instead of the url,
         // so wildcard actions will have the same validator
         // WW-3753: Using the config name instead of the context only for 
wildcard actions to keep the flexibility
         // provided by the original design (such as mapping different contexts 
to the same action and method if desired)
         // WW-4536: Using NamedVariablePatternMatcher allows defines actions 
with patterns enclosed with '{}'
-        String configName = config.getName();
-        if (configName.contains(ActionConfig.WILDCARD) || 
(configName.contains("{") && configName.contains("}"))) {
+        // WW-3530: the config-name substitution only makes sense for the 
action's own class; a visited object
+        // (visitor validator) carries a stable, explicit context that must 
remain part of the key
+        if (validatingActionClass && wildcard) {
             sb.append(configName);
             sb.append("|");
             sb.append(proxy.getMethod());

Reply via email to