Skip to content

WW-5729 fix(jasperreports): override HashMap.get/containsKey in ValueStackShadowMap - #1920

Merged
lukaszlenart merged 2 commits into
mainfrom
WW-5729-shadowmap-override
Sep 12, 2026
Merged

WW-5729 fix(jasperreports): override HashMap.get/containsKey in ValueStackShadowMap#1920
lukaszlenart merged 2 commits into
mainfrom
WW-5729-shadowmap-override

Conversation

@lukaszlenart

@lukaszlenart lukaszlenart commented Sep 12, 2026

Copy link
Copy Markdown
Member

Fixes 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(since = "7.4.0", forRemoval = true) delegates for binary compatibility — removal tracked in WW-5730 at 8.0.0.
  • 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

@lukaszlenart
lukaszlenart marked this pull request as draft September 12, 2026 09:07
@lukaszlenart
lukaszlenart force-pushed the WW-5729-shadowmap-override branch from 2e039a6 to 9a7fdb6 Compare September 12, 2026 09:11
…StackShadowMap

The two methods took a String parameter, so they overloaded rather than
overrode HashMap.get(Object) and containsKey(Object). JasperReports holds
the parameter map as java.util.Map and calls the Object variants, which
meant the value-stack fallback the class exists for never ran when a
report was filled: only the entries the result put explicitly reached
JasperReports, and a declared parameter exposed as an action property
rendered as null.

The Object overrides were the original code; 2908d74 (2019, "Minor
code optimization") narrowed them to String when it added the generics,
and the regression first shipped in 6.0.0. The jasperreports7 copy
already declares both as @OverRide with an Object parameter.

Both copies now let an explicit map entry win even when its value is
null, so containsKey and get agree and JasperReports skips the default
value expression consistently. The String overloads stay in the 6.x
plugin as deprecated delegates for binary compatibility.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@lukaszlenart
lukaszlenart force-pushed the WW-5729-shadowmap-override branch from 9a7fdb6 to 8853c4d Compare September 12, 2026 09:13
@lukaszlenart
lukaszlenart marked this pull request as ready for review September 12, 2026 09:14
The deprecated String delegates are reachable only by callers holding a
ValueStackShadowMap reference, so the result-level tests never hit them.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@sonarqubecloud

Copy link
Copy Markdown

Quality Gate Failed Quality Gate failed

Failed conditions
9.0% Duplication on New Code (required ≤ 3%)

See analysis details on SonarQube Cloud

@lukaszlenart
lukaszlenart merged commit 8c66d8d into main Sep 12, 2026
12 of 13 checks passed
@lukaszlenart
lukaszlenart deleted the WW-5729-shadowmap-override branch September 12, 2026 09:57
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