This is an automated email from the ASF dual-hosted git repository. lukaszlenart pushed a commit to branch WW-3871-typeconversion-key-derivation in repository https://gitbox.apache.org/repos/asf/struts.git
commit f3952e487165f9ab5500ea0cb55dd0167e098743 Author: Lukasz Lenart <[email protected]> AuthorDate: Sat Jul 25 15:00:57 2026 +0200 WW-3871 docs: note interaction with the 7.3.0 converter mapping cache Records that addConverterMapping runs inside the computeMappingIfAbsent builder introduced by WW-5539, which executes outside any lock, so the new field pass adds no deadlock risk but must stay side-effect free. Co-Authored-By: Claude Opus 5 <[email protected]> --- ...07-25-WW-3871-typeconversion-key-derivation-design.md | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/docs/superpowers/specs/2026-07-25-WW-3871-typeconversion-key-derivation-design.md b/docs/superpowers/specs/2026-07-25-WW-3871-typeconversion-key-derivation-design.md index 340968138..5e957a7e6 100644 --- a/docs/superpowers/specs/2026-07-25-WW-3871-typeconversion-key-derivation-design.md +++ b/docs/superpowers/specs/2026-07-25-WW-3871-typeconversion-key-derivation-design.md @@ -133,7 +133,21 @@ It skips `static` and synthetic fields, which also makes the interface case a no (`getDeclaredFields()` on an interface returns its constants). A field's own name is the property name; no getter/setter parsing is involved. -### 4. Error handling +### 4. Interaction with the 7.3.0 mapping cache + +`addConverterMapping` runs inside the builder that `XWorkConverter.buildConverterMapping` hands to +`TypeConverterHolder.computeMappingIfAbsent` (WW-5539). That builder deliberately executes **outside** +any lock — `StrutsTypeConverterHolder.java:171-188` documents why: it instantiates, and under +`SpringObjectFactory` autowires, arbitrary user-supplied `TypeConverter`s, so running it under a +`ConcurrentHashMap` bin lock would risk `IllegalStateException("Recursive update")` or self-deadlock +if any of that re-enters conversion. + +The new field pass instantiates converters exactly as the existing method pass does, so it inherits +that safety and adds no new hazard. The one consequence to respect: under first-access contention the +builder may run more than once for the same class, so every pass must stay free of side effects +outside the `mapping` map it is handed. + +### 5. Error handling | Situation | Today | After | |---|---|---|
