lukaszlenart opened a new pull request, #1766:
URL: https://github.com/apache/struts/pull/1766

   Fixes [WW-5641](https://issues.apache.org/jira/browse/WW-5641)
   
   ## Problem
   
   A custom JSON writer/reader configured the documented way is silently 
ignored on the 7.2.x line — the framework always uses the default 
`StrutsJSONWriter` / `StrutsJSONReader`:
   
   ```xml
   <bean type="org.apache.struts2.json.JSONWriter" name="flexJSONWriter"
         class="org.demo.FlexJSONWriter" scope="prototype"/>
   <constant name="struts.json.writer" value="flexJSONWriter"/>
   ```
   
   This worked on 7.1.x and regressed in 7.2.x. The extension point is still 
documented at <https://struts.apache.org/plugins/json/>, so this is a 
regression, not an intended API change.
   
   ## Root cause
   
   Writer/reader selection moved from a **runtime, by-name lookup** (7.1.x) to 
a **container-build-time alias** (7.2.x, introduced with the JSON hardening 
rework that added `<bean-selection>` to the plugin's `struts-plugin.xml`).
   
   `XmlDocConfigurationProvider.registerBeanSelection()` invokes 
`JSONBeanSelectionProvider.register()` → 
`AbstractBeanSelectionProvider.alias()` **inline, the moment the 
`<bean-selection>` element is parsed** in the JSON plugin's 
`struts-plugin.xml`. At that instant the shared `props` hold only the plugin's 
own `struts.json.writer=struts`; the application `struts.xml` is a *later* 
`ContainerProvider` whose override bean/constant have not been folded in yet. 
So `alias()` locks `JSONWriter/DEFAULT_NAME → StrutsJSONWriter`, and nothing 
re-runs the selection once the app config loads. `JSONUtil` in 7.2.x injected 
that frozen default binding.
   
   The 7.1.x code was immune because `JSONUtil` resolved the writer/reader by 
the constant value at container-use time — after the full container (including 
the app `struts.xml`) was built.
   
   ## Fix
   
   Restore 7.1.x-style deferred resolution, confined to `JSONUtil`: inject the 
`Container` and resolve the writer/reader from the **effective** 
`struts.json.writer` / `struts.json.reader` constant values (named lookup) at 
injection time, instead of relying on the build-time default alias. 
`setWriter`/`setReader` remain public plain setters (only `@Inject` removed).
   
   Preserves the 7.2.x hardening:
   - `StrutsJSONWriter` / `StrutsJSONReader` remain the shipped defaults.
   - JSON DoS limits (`maxDepth`, `maxElements`, `maxLength`, 
`maxStringLength`, `maxKeyLength`) untouched — their `@Inject` setters still 
fire on the resolved bean.
   - `JSONUtil` and the writer/reader stay `prototype`; `serialize(...)` never 
touches `container`, so per-instance resolution and thread-safety of the 
bean-info cache are unchanged.
   
   The `<bean-selection>` / default alias is left in place (harmless) so any 
external `container.getInstance(JSONWriter.class)` keeps working.
   
   ## Test
   
   `JSONWriterOverrideTest` boots the real `Dispatcher` config chain 
(`struts-default.xml,struts-plugin.xml,struts-json-override.xml`, in that 
order) so the provider ordering that causes the bug is reproduced, and asserts 
the **effective** writer (serialize sentinel) and reader 
(`getReader().getClass()`) — covering both `struts.json.writer` and 
`struts.json.reader`. Verified failing before the fix, passing after. Full 
`struts2-json-plugin` suite: 127/127 green.
   
   🤖 Generated with [Claude Code](https://claude.com/claude-code)
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to