Skip to content

WW-5641 Restore struts.json.writer / struts.json.reader override in JSON plugin#1766

Open
lukaszlenart wants to merge 3 commits into
mainfrom
WW-5641-json-writer-reader-override
Open

WW-5641 Restore struts.json.writer / struts.json.reader override in JSON plugin#1766
lukaszlenart wants to merge 3 commits into
mainfrom
WW-5641-json-writer-reader-override

Conversation

@lukaszlenart

@lukaszlenart lukaszlenart commented Jul 6, 2026

Copy link
Copy Markdown
Member

Fixes 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:

<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

The 7.2.x JSON hardening rework added a <bean-selection name="jsonBeans" .../> element to the plugin's struts-plugin.xml. XmlDocConfigurationProvider.registerBeanSelection() runs that element inline, at plugin-parse time — before the application's struts.xml folds its override bean and struts.json.writer constant into the shared props. AbstractBeanSelectionProvider.alias() binds the default name only once (guarded), so it locks JSONWriter/JSONReader DEFAULT_NAME → StrutsJSONWriter/StrutsJSONReader and never re-selects when the app config loads afterward.

Fix

Move the <bean-selection> from struts-plugin.xml into a new struts-deferred.xml. Dispatcher.init() loads struts-deferred.xml last — after the application config and after core's StrutsBeanSelectionProvider — precisely because it is "sensitive to loading order such as 'bean-selection' elements" (per the framework's own comment). Running late, alias() reads the effective struts.json.writer / struts.json.reader value and aliases the default binding to the application's override.

This is the established in-tree convention: the velocity plugin already keeps its <bean> definitions in struts-plugin.xml and its <bean-selection> in struts-deferred.xml; core's own StrutsBeanSelectionProvider is likewise registered to run after all XML config. The JSON plugin was the outlier.

  • No Java changes — JSONUtil is unchanged from main.
  • StrutsJSONWriter / StrutsJSONReader remain the shipped defaults when no override is configured; DoS limits untouched.
  • Fixes the container binding itself, so container.getInstance(JSONWriter.class) resolves to the override for any consumer.

Test

JSONWriterOverrideTest boots the real Dispatcher chain (struts-deferred.xml is loaded last by the framework, so it is intentionally omitted from the explicit config) and asserts, for both writer and reader, at both levels: the default container binding (container.getInstance(...)) and the effective use (JSONUtil.serialize(...) sentinel / getReader().getClass()). Verified failing before the element is moved, passing after. Full struts2-json-plugin suite: 129/129 green; apache-rat:check clean.

🤖 Generated with Claude Code

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@lukaszlenart lukaszlenart force-pushed the WW-5641-json-writer-reader-override branch from 48c3060 to ec4ac87 Compare July 6, 2026 18:04
lukaszlenart and others added 2 commits July 6, 2026 20:18
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The JSON plugin declared <bean-selection> in struts-plugin.xml, which runs
at plugin-parse time, before the application struts.xml is folded in. That
froze the JSONWriter/JSONReader default binding to StrutsJSONWriter/Reader,
so struts.json.writer / struts.json.reader overrides were ignored.

Move the element to struts-deferred.xml, which Dispatcher loads last (after
the app config and core's StrutsBeanSelectionProvider), so the alias honors
the override. Mirrors the velocity plugin. JSONUtil is unchanged from main.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@lukaszlenart lukaszlenart force-pushed the WW-5641-json-writer-reader-override branch from ec4ac87 to 4ecf29c Compare July 6, 2026 18:18
@sonarqubecloud

sonarqubecloud Bot commented Jul 6, 2026

Copy link
Copy Markdown

@lukaszlenart lukaszlenart marked this pull request as ready for review July 6, 2026 18:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant