lukaszlenart opened a new pull request, #1782:
URL: https://github.com/apache/struts/pull/1782
## What
Follow-up refactor of the JSON plugin's reader/writer thread-safety handling.
The interim fixes in #1775 / #1776 confined `StrutsJSONReader` /
`StrutsJSONWriter` per-operation
state to a `ThreadLocal`, created fresh per call and cleared in a `finally`.
That works, but it
relies on a per-request cleanup contract and keeps a single reader/writer
instance shared across
threads.
This change removes that machinery in favour of a simpler, structural
approach: the singleton
`JSONInterceptor` now obtains a **fresh `JSONUtil` (and thus a fresh reader
+ writer) per request**
via the container, so no parse/serialize state is ever shared across threads
in the first place.
With instances no longer shared, `StrutsJSONReader` / `StrutsJSONWriter`
revert to plain,
single-use instance fields and are documented as not thread-safe.
## Why this is safe / minimal
- `JSONResult` was already built per request (it injects a `prototype`
`JSONUtil`) and is
untouched — it never shared state.
- `JSONReader`, `JSONWriter` and `JSONUtil` are already registered
`scope="prototype"`, so
`container.getInstance(JSONUtil.class)` hands back a fresh graph each call
and continues to honour
the `struts.json.reader` / `struts.json.writer` overrides.
- This mirrors an existing in-tree pattern (`AbstractFileUploadInterceptor`
injects `Container` and
resolves collaborators per request).
## Changes
- `JSONInterceptor`: drop the cached `@Inject JSONUtil` field; inject
`Container` and resolve a
fresh `JSONUtil` per `intercept()` (new `protected getJSONUtil()` seam).
- `StrutsJSONReader` / `StrutsJSONWriter`: revert `ThreadLocal` state back
to plain instance fields;
add a "not thread-safe — obtain a fresh instance per operation" class note.
- Tests: the old shared-single-instance concurrency tests asserted an
invariant this design
intentionally drops (a single shared instance being safe), so they are
replaced by an
interceptor-level test asserting a distinct `JSONUtil`/reader is obtained
per acquisition.
## Testing
`mvn test -DskipAssembly -pl plugins/json` → all green (141 tests).
`JSONWriterOverrideTest` passes,
confirming `struts.json.reader` / `struts.json.writer` overrides still
resolve through the container.
## Notes
- Public/protected extension-method signatures of the reader/writer are
unchanged; custom
subclasses and reader/writer overrides continue to work.
- The interceptor freshness test asserts distinctness via `getJSONUtil()`
(JSONUtil exposes no
writer getter); this guards against re-caching/singleton-scoping the util.
Fixes [WW-5650](https://issues.apache.org/jira/browse/WW-5650)
🤖 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]