[
https://issues.apache.org/jira/browse/WW-5729?focusedWorklogId=1041092&page=com.atlassian.jira.plugin.system.issuetabpanels:worklog-tabpanel#worklog-1041092
]
ASF GitHub Bot logged work on WW-5729:
--------------------------------------
Author: ASF GitHub Bot
Created on: 12/Sep/26 09:07
Start Date: 12/Sep/26 09:07
Worklog Time Spent: 10m
Work Description: lukaszlenart opened a new pull request, #1920:
URL: https://github.com/apache/struts/pull/1920
Fixes [WW-5729](https://issues.apache.org/jira/browse/WW-5729)
## What
`ValueStackShadowMap` in the `jasperreports` plugin is meant to fall back to
`ValueStack.findValue(name)` for any report parameter not put in the map
explicitly, so a parameter declared in the `.jasper` can be resolved straight
from the action. Its `containsKey(String)` / `get(String)` were *overloads* of
the `HashMap` methods, not overrides, and JasperReports — which holds the map
as `java.util.Map` — calls the `Object` variants. The fallback therefore never
ran: a declared parameter exposed only as an action property rendered as `null`.
This is a regression: the `Object` overrides were the original code,
`2908d746c` (2019, "Minor code optimization") narrowed them to `String` while
adding the generics, and it first shipped in 6.0.0. The `jasperreports7` copy
already has the `@Override` form.
## Changes
- `jasperreports/ValueStackShadowMap`: `containsKey(Object)` / `get(Object)`
are now real overrides; the `String` overloads stay as deprecated delegates for
binary compatibility.
- Both copies: an explicit map entry wins even when its value is `null`, so
`containsKey` and `get` agree and JasperReports skips the parameter's
default-value expression consistently.
- Tests in both plugins: `$P{title}` resolved from an action getter with no
`reportParameters` (watched failing with `null Report` before the fix), and an
explicit `title → null` entry not shadowed by the getter.
## Behaviour change — for the version notes
Users of the 6.x-line plugin whose reports declare a parameter with the same
name as an action property (or a Struts context key such as `session`,
`request`, `parameters`, `locale`) will see that parameter start resolving from
the value stack instead of its default-value expression, as the class Javadoc
has always described and as the `jasperreports7` plugin already does. The
lookup is type-blind — a `Long` parameter meeting an `int` getter, or a
`session` parameter meeting the Struts `SessionMap`, fails at fill time with a
`ClassCastException`. Rename the report parameter or supply it through
`reportParameters` in that case.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Issue Time Tracking
-------------------
Worklog Id: (was: 1041092)
Remaining Estimate: 0h
Time Spent: 10m
> JasperReports plugin: ValueStackShadowMap overloads get/containsKey instead
> of overriding them, so the value-stack fallback never reaches JasperReports
> -------------------------------------------------------------------------------------------------------------------------------------------------------
>
> Key: WW-5729
> URL: https://issues.apache.org/jira/browse/WW-5729
> Project: Struts 2
> Issue Type: Bug
> Components: Plugin - JasperReports
> Reporter: Lukasz Lenart
> Assignee: Lukasz Lenart
> Priority: Minor
> Fix For: 7.4.0
>
> Time Spent: 10m
> Remaining Estimate: 0h
>
> {{org.apache.struts2.views.jasperreports.ValueStackShadowMap}} (the
> {{struts2-jasperreports-plugin}}, JasperReports 6.x line) is documented as a
> {{HashMap}} whose {{containsKey}} and {{get}} fall back to
> {{ValueStack.findValue(key)}} when the key is not in the map, so that a
> report parameter declared in the {{.jasper}} can be resolved straight from
> the action. That is how {{JasperReportsResult}} hands the parameter map to
> {{JasperFillManager.fillReport}}.
> The two methods are declared as
> {code:java}public boolean containsKey(String key)
> public Object get(String key)
> {code}
> The {{HashMap}} methods they are meant to replace take {{Object}}, so these
> are overloads, not overrides (the Javadoc says "overriding HashMap
> implementation", and there is no {{@Override}}). JasperReports holds the
> parameters as a {{java.util.Map}} and calls {{get(Object)}} /
> {{containsKey(Object)}}, which resolve to the plain {{HashMap}}
> implementation. The value-stack fallback therefore never runs when called
> through JasperReports; only the entries the result puts explicitly
> ({{reportDirectory}}, {{REPORT_LOCALE}}, {{REPORT_TIME_ZONE}}, and the
> {{reportParameters}} map) reach the fill.
> The copy in the {{struts2-jasperreports7-plugin}}
> ({{org.apache.struts2.views.jasperreports7.ValueStackShadowMap}}, WW-5455)
> declares both methods with an {{Object}} parameter and {{@Override}}, so the
> two plugins behave differently for the same report and action.
> Fix: change the parameter type to {{Object}} and add {{@Override}}, matching
> the JR7 copy, with a test that fills a report whose declared parameter is
> only available as an action property.
> Note this is a behaviour change for the 6.x plugin: after the fix, a declared
> report parameter that the action exposes as a property but does not put in
> {{reportParameters}} starts being resolved from the value stack, as the
> Javadoc has always claimed. Worth a line in the version notes.
> Found while triaging WW-3245; no security impact (the fallback keys are the
> parameter names compiled into the developer's {{.jasper}}, not request data).
--
This message was sent by Atlassian Jira
(v8.20.10#820010)