Skip to content

Modernize examples to Apache Struts 7.3.0 - #544

Merged
lukaszlenart merged 13 commits into
mainfrom
feat/struts-730-modernization
Aug 14, 2026
Merged

Modernize examples to Apache Struts 7.3.0#544
lukaszlenart merged 13 commits into
mainfrom
feat/struts-730-modernization

Conversation

@lukaszlenart

Copy link
Copy Markdown
Member

Modernizes all 47 example applications to the current Apache Struts 7.3.0 standard.

What changed

Area Scope
Struts version 7.2.17.3.0 (parent POM, plus sitemesh3's own override)
Struts config DTDs 54 files → struts-6.5.dtd over https
Validator DTDs 13 files → xwork-validator-1.0.3.dtd over https
Tiles DTDs 7 files → tiles-config_3_0.dtd (unknown-handler was on 2.0)
Maven POM schema 48 POMs → https://maven.apache.org/xsd/maven-4.0.0.xsd
web.xml 29 descriptors migrated to Jakarta EE 6.0; all 47 now current
@StrutsParameter 17 annotations across 7 modules
Naming "Struts 2" → "Apache Struts" in POM/README prose

The part worth reviewing carefully

struts.parameters.requireAnnotations has defaulted to true since before 7.2.1, so any action missing @StrutsParameter was already silently dropping every submitted parameter. This branch fixes seven such modules:

  • crudgetPerson() needed depth = 2 (person.country.countryId)
  • shiro-basicLoginAction.username/password, WelcomeAction.username
  • unknown-handlerLogin.email/password
  • validation-messagesLogin.username/password
  • bean-validation, themes-overridegetPersonBean() needed depth = 1
  • mailreader2MailreaderSupport: 5 setters + getUser()/getSubscription()

bean-validation was the most misleading of these: with parameters dropped it validated an empty bean, so the demo appeared to work while showing violations unrelated to what the user typed.

Annotations follow what ParametersInterceptor actually inspects — depth 0 on the setter, depth ≥ 1 on the getter — and nested POJOs are deliberately left unannotated, since only the action's root property is authorized.

Verification

  • mvn clean test green on JDK 17 and 21 (matching CI)
  • xmllint clean across all XML
  • Jetty runtime checks confirming nested parameter binding works in crud and still works in the untouched control form-tags
  • dependency-check reports 5 CVSS ≥ 7 findings; all are pre-existing — re-running the profile pinned to 7.2.1 reproduces them identically, so the bump introduces none. Left unsuppressed deliberately: suppression is a maintainer's judgment. (The struts2-tiles-plugin hit looks like a CPE false positive — the plugin has no org.apache.tiles dependency.)

Known follow-ups (not addressed here)

  • Arrays.asList(getCarModels()) NPEs on the default happy path in form-tags, control-tags, bean-validation, and crud — submit the form without ticking a car model. Pre-existing; worth its own issue.
  • The rename covers metadata only; ~104 "Struts 2" strings remain in the JSPs, so page titles a learner sees still say "Struts 2".
  • interceptors/pom.xml describes itself as a form-XML-validation example (pre-existing copy-paste).
  • basic-struts/README.md intentionally still quotes Welcome To Struts 2! because index.jsp renders exactly that — documentation accuracy over branding consistency.

Design and implementation notes are committed under docs/superpowers/.

🤖 Generated with Claude Code

lukaszlenart and others added 13 commits August 14, 2026 11:33
Covers the version bump, DTD/schema normalization to struts-6.5, the
@StrutsParameter audit across action classes, and the Apache Struts
renaming.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Six tasks covering the version bump, DOCTYPE and web.xml schema sweeps,
eight verified @StrutsParameter fixes, the Apache Struts renaming, and
final verification.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Struts config DTDs to 6.5, XWork validator DTDs to 1.0.3, Tiles to 3.0,
and Maven POM schema URLs to the current location. All system IDs now
use https.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Brings the 29 descriptors still on Servlet 2.3-3.1 era schemas in line
with the 18 already using web-app_6_0.xsd.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Eight parameters across crud, shiro-basic, unknown-handler and
validation-messages were silently dropped: struts.parameters.requireAnnotations
has defaulted to true since before 7.2.1, and these setters and getters
were never annotated.

Depth 0 parameters are annotated on the setter and nested parameters on
the getter, matching what ParametersInterceptor actually inspects.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The project has been Struts 7 for some time; the Struts 2 naming in POM
names and descriptions was stale. Also corrects the root README's claim
that every module has a README (6 of 47 do), fixes the broken Releases
link, and moves remaining http:// links to https://.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The bulk substitution for the Struts 2 rename only matched the spaced
form, missing 5 prose occurrences of the unspaced Struts2 in POM
names/descriptions and one README. Follow-up to 6967f73.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The bulk rename changed a fenced-code-block quote of the app's rendered
output to "Welcome to Apache Struts!", but index.jsp still prints
"Welcome To Struts 2!" (92 similar Struts 2/Struts2 strings remain across
example JSPs, out of scope for this branch). The README now told readers
to expect output the app never produces; reverted that one line to the
original text so it matches what actually renders.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The original audit matched only name= on <s:*> tags (missing key=,
which also sets the parameter name) and did not consider accessors
inherited from a superclass. This let three modules silently drop
every submitted parameter: bean-validation and themes-override
(EditAction.getPersonBean(), whose JSPs use key=) and mailreader2
(MailreaderSupport, the shared base class for RegistrationAction,
SubscriptionAction, and LoginAction). Adds 9 annotations across the
three modules, bringing the running total to 17 across 8 modules, and
corrects the two now-false claims in the modernization plan doc.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Line 23 read "Welcome to Struts 2!" but index.jsp:10 renders
"Welcome To Struts 2!" (capital T). Commit 64baa49 was meant to make
these match but was off by one character.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
RegisterAction.getPersonBean() declared depth = 10, but
register-input.jsp only ever submits personBean.firstName, .lastName,
.email, and .age — depth 1. This module exists to teach the
annotation, so an inflated depth taught the wrong idiom and needlessly
widened what the framework would bind from a request. Verified no JSP
or validation descriptor in the module submits anything deeper.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Corrected documentation to distinguish between 7 modules (not 8)
and 8 classes containing the 17 @StrutsParameter annotations.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@lukaszlenart
lukaszlenart merged commit 3309300 into main Aug 14, 2026
2 checks passed
@lukaszlenart
lukaszlenart deleted the feat/struts-730-modernization branch August 14, 2026 11:34
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