[
https://issues.apache.org/jira/browse/WW-3530?focusedWorklogId=1032154&page=com.atlassian.jira.plugin.system.issuetabpanels:worklog-tabpanel#worklog-1032154
]
ASF GitHub Bot logged work on WW-3530:
--------------------------------------
Author: ASF GitHub Bot
Created on: 25/Jul/26 10:08
Start Date: 25/Jul/26 10:08
Worklog Time Spent: 10m
Work Description: lukaszlenart opened a new pull request, #1811:
URL: https://github.com/apache/struts/pull/1811
Fixes [WW-3530](https://issues.apache.org/jira/browse/WW-3530)
## Problem
Two visitor field validators declared on the same field with different
`context`
params (e.g. `basic` and `additional`) collide in the validator cache under
**wildcard / named-pattern actions**: both produce the same cache key, so the
first context's validators are returned for both and the second context's
validators are silently dropped.
Originally reported in 2010 (v2.2.1) when the cache key omitted `context`
entirely. WW-2996 / WW-3753 / WW-4536 later reworked the key so `context` is
included for normal actions — fixing the report for non-wildcard actions. The
defect still reproduces for wildcard actions, where the key intentionally
substitutes the action config name for `context`.
## Root cause
`AnnotationActionValidatorManager.buildValidatorKey` substitutes the action's
config name + method for `context` whenever the **current action** is a
wildcard/named-pattern action. That substitution is designed for the action's
own class (where `context` is the volatile URL-derived action name that
WW-2996
must not key on). But it was applied too broadly — it also fired when
validating
a **visited object** under a visitor validator, whose `context` is a stable,
explicit param, and wrongly discarded it.
## Fix
Narrow the substitution to the case it was designed for: apply the
config-name
key only when the class being validated is the action's own class
(`clazz.equals(invocation.getAction().getClass())`). For any other class (a
visited object), key on `context` — matching `DefaultActionValidatorManager`.
The request-validation hot path (`ValidationInterceptor` →
`getValidators(action.getClass(), …)`) always validates the live action
instance's own class, so WW-2996's single-cache-entry-per-wildcard-action
behavior is fully preserved. The cache-key change only affects cache
*reuse*; it
never changes *which* validators load (`buildValidatorConfigs` receives
`context`
directly).
## Tests
- New unit tests in `AnnotationActionValidatorManagerTest`:
- visited class under a wildcard action → distinct keys per context (the
failing-before / passing-after case)
- action's own class under a wildcard action → key ignores context (WW-2996
behavior pinned)
- Regression: full `AnnotationActionValidatorManagerTest` (14/14) and
`VisitorFieldValidatorTest` / `VisitorFieldValidatorModelTest` /
`DefaultActionValidatorManagerTest` (23/23) pass.
- **Draft note:** the full `core` module suite has not yet been run in this
branch — to be completed before marking ready for review.
## Known limitations (follow-up ticket to be filed)
Both need an explicit visitor signal threaded through the manager API to fix
cleanly, and are memory-only (correct validators still load):
- **Default-context visitor under a wildcard action:** a visitor validator
with
no explicit `context` defaults to the resolved action name, which is
volatile
under a wildcard action — so the visited-class key moves from stable
(`configName|method`) to volatile, causing bounded WW-2996-style cache
growth.
Disappears when the visitor declares an explicit `context`.
- **`<s:form>` client-side JS-validation render path:** resolves the action
class by name rather than from the live action instance, so for a
cross-action or proxied form the action's own top-level lookup falls to the
`context` branch under a wildcard action (extra cache entries, correctness
unaffected).
Design spec and implementation plan are included under `docs/superpowers/`.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Issue Time Tracking
-------------------
Worklog Id: (was: 1032154)
Remaining Estimate: 0h
Time Spent: 10m
> Invalid cache key in AnnotationActionValidationManager.buildValidatorKey
> when using visitor field validators
> -------------------------------------------------------------------------------------------------------------
>
> Key: WW-3530
> URL: https://issues.apache.org/jira/browse/WW-3530
> Project: Struts 2
> Issue Type: Bug
> Components: XML Validators
> Affects Versions: 2.2.1
> Reporter: Johnny Yu
> Assignee: Lukasz Lenart
> Priority: Major
> Fix For: 7.3.0
>
> Time Spent: 10m
> Remaining Estimate: 0h
>
> Error scenerio:
> MyAction-validation.xml:
> <validators>
> <field name="myField"> <!-- MyClass -->
> <field-validator type="visitor">
> <param name="context">basic</param>
> <param name="appendPrefix">true</param>
> <message/>
> </field-validator>
> </field>
> <field name="myField">
> <field-validator type="visitor">
> <param name="context">additional</param>
> <param name="appendPrefix">true</param>
> <message/>
> </field-validator>
> </field>
> </validators>
> In this case, validators in MyClass-basic-validation.xml will be executed two
> times, but validators in MyClass-additional-validation.xml will just ignored.
> The problem is caused by
> AnnotationActionValidationManager.buildValidatorKey(Class) which returns the
> same cache key for the validator cache.
> The current cache key is created by:
> StringBuilder sb = new StringBuilder(clazz.getName());
> sb.append("/");
> sb.append(proxy.getConfig().getName());
> sb.append("|");
> sb.append(proxy.getMethod());
> The context is not a part of the cache key. Therefore, the two visitor
> validator will just get the same cache key.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)