Vote passed with result: GA +1 x3 (binding) Cheers Łukasz
pon., 28 wrz 2026 o 09:15 Lukasz Lenart <[email protected]> napisał(a): > > The Apache Struts 7.4.0 test build is available. This release contains a > large number of breaking changes and deprecations, mostly around > parameter binding and the REST plugin, together with bug fixes and > improvements: > > Breaking changes > > - Five dev-mode configuration setters were removed from > SecurityMemberAccess (useDevMode, useDevModeExcludedClasses, > useDevModeExcludedPackageNamePatterns, useDevModeExcludedPackageNames, > useDevModeExcludedPackageExemptClasses) and the remaining configuration > setters are no longer container-injected; the struts.devMode.* settings > themselves are unchanged [WW-5675]. > - With struts.parameters.requireAnnotations=true, a ModelDriven action's > own members now require @StrutsParameter; only the model's members stay > exempt, and struts.parameters.requireAnnotations.transitionMode is the > migration path [WW-5698]. > - @StrutsParameter enforcement now recognises fluent (non-void) setters, > so an unannotated fluent setter is rejected like a void one [WW-5709]. > - A nested property annotated on a ModelDriven action itself is now > primed into the OGNL allowlist, so it binds under > struts.allowlist.enable=true [WW-5710]. > - A one-argument get* or two-argument set* method that is not the > indexed accessor of a real property is no longer invoked during > parameter binding [WW-5697]. > - An interceptor-ref name repeated in one action's interceptor list now > applies each ref's own params to a WithLazyParams interceptor instead of > the first ref's [WW-5663]. > - struts.csp.nonceSource is now honoured alongside > struts.csp.nonce.source, so a configuration carrying > struts.csp.nonceSource=request switches to request-scoped CSP nonces on > upgrade [WW-5669]. > - Forms rendered with the html5 theme now carry HTML5 constraint > attributes derived from the action's validators, so browsers validate > before submitting [WW-5695]. > - The Tiles plugin's legacy OGNL: attribute evaluator is disabled by > default and throws an EvaluationException; > struts.tiles.ognl.legacy.enabled=true restores it for the transition > [WW-5713]. > - The REST plugin's restDefaultStack and the Bean Validation plugin's > beanValidationDefaultStack now include the coep, coop and fetchMetadata > interceptors, so a REST API serving cross-site browser clients must > configure fetchMetadata.exemptedPaths or disable that ref [WW-5718]. > - The REST plugin rejects a request body longer than > struts.rest.content.maxLength (default 2097152) with > RequestBodyTooLargeException before the action runs [WW-5723]. > - REST body authorization now keys off the Java member name rather than > the Jackson wire name, so a member renamed with @JsonProperty is > authorized by its own annotation [WW-5715]. > - The REST plugin's Jackson handlers no longer merge a request body into > a polymorphic property that already holds a value; the value is replaced > through the authorized path and the body must carry the type id > [WW-5726]. > - With struts.parameters.requireAnnotations=true, the id property of a > type using a property-based @JsonIdentityInfo is subject to > @StrutsParameter in REST bodies like any other property [WW-5727]. > - A REST body object dropped after a @StrutsParameter redaction no > longer leaks its remaining fields into the enclosing object [WW-5747]. > - The JasperReports plugin's ValueStackShadowMap resolves report > parameters not passed explicitly from the value stack again, so a report > parameter named like an action property now receives that value > [WW-5729]. > - The JasperReports 7 plugin no longer brings > net.sf.jasperreports:jasperreports transitively; applications must > declare it (and jasperreports-pdf for PDF output) themselves [WW-5735]. > - Convention-plugin wildcard action names containing a path-spanning ** > now sort after every pattern without one, so a/*/* is matched before > a/** [WW-5743]. > > Deprecations > > - The eleven remaining SecurityMemberAccess configuration setters > (useAllowStaticFieldAccess … useDisallowDefaultPackageAccess) are > deprecated; configuration is read through SecurityMemberAccessConfig. > Removal is WW-5682 [WW-5675]. > - The constant name struts.csp.nonceSource > (StrutsConstants.STRUTS_CSP_NONCE_SOURCE_LEGACY) and > DefaultCspSettings.setLegacyNonceSource are deprecated; use > struts.csp.nonce.source [WW-5669]. > - JavaScript client-side validation in the xhtml and css_xhtml themes > (validate="true" on <s:form>, Form.getValidators) is deprecated; use the > html5 theme's constraint attributes. Removal is WW-5696 [WW-5694]. > - ReflectionContextState.DENY_INDEXED_ACCESS_EXECUTION is deprecated. > Removal is WW-5699 [WW-5697]. > - RestfulActionMapper and Restful2ActionMapper are deprecated; use the > REST plugin. Removal is WW-5708 [WW-5707]. > - StrutsParameterAuthorizer.hasValidAnnotatedPropertyDescriptor is > deprecated; use findBindableAccessor with hasValidAnnotatedMethod. > Removal is WW-5739 [WW-5709]. > - The Tiles OGNLAttributeEvaluator and the > struts.tiles.ognl.legacy.enabled constant are deprecated. Removal is > WW-5714 [WW-5713]. > - The REST plugin's one-argument > AuthorizingSettableBeanProperty(SettableBeanProperty) constructor is > deprecated; use the (SettableBeanProperty, String memberName) overload. > Removal is WW-5744 [WW-5715]. > - ValueStackShadowMap.get(String) and containsKey(String) in the > JasperReports plugin are deprecated; use the Object overloads [WW-5729]. > > Rejected requests > > Seven tickets were closed against this release without a change to > shipped code. They are listed here so the decision is visible rather > than silent. > > [WW-2278] - Move S2 Tags into a plugin - will not be implemented as > filed; core depends on the tag packages, and the lean-core direction is > Struts 8 scope under its own ticket. > [WW-2975] - client side validation and components with forms - will not > be implemented; the JavaScript validator is deprecated (WW-5694) and > superseded by HTML5 constraint attributes (WW-5695) rather than > repaired. > [WW-3193] - Form action always inherits parent extension - closed as > Duplicate of WW-4164, where the per-package extension design continues. > [WW-3226] - Add optional support to AliasInterceptor to overwrite > aliased parameters - will not be implemented; interceptor ordering > already gives both behaviours, now documented and pinned by tests. > [WW-3232] - New Cookie Interceptor - will not be implemented; reading is > covered by CookieInterceptor with @StrutsParameter, writing by > CookieProvider. > [WW-3257] - Get Controller bean from Spring - closed as Not A Problem; > the Spring plugin already creates and autowires the controller, and a > bean registered under the fully qualified class name is picked up. > [WW-3338] - <s:hidden> tag should interpret its value attribute same as > the other tags do. - will not be implemented; String-valued attributes > are parsed for the %{} notation by design, and the Tag Syntax page is > corrected. > > Bug > [WW-3353] - StrutsTestCase doesn't work with rest-plugin > [WW-5663] - DefaultActionInvocation.mergedParams resolves interceptor > params by name, merging the wrong ref when a name repeats > [WW-5667] - Performance Issue: SecurityMemberAccess re-parses excluded > packages/classes config string on every OGNL access — O(n) String.split > per request > [WW-5669] - CSP nonce source is not configurable: struts.csp.nonceSource > never reaches the injection point > [WW-5670] - Dispatcher.getLocale logs "defaulting to request locale" for > a locale that may not come from the request > [WW-5685] - DefaultConversionFileProcessor silently drops the rest of a > -conversion.properties file after the first already-mapped key > [WW-5686] - <s:date/> renders a java.sql.Date with the current > wall-clock time, making DateTest.testJavaSqlDate flaky > [WW-5688] - RestActionMapper maps URIs with an id into the empty > namespace, so actions declared at namespace "/" 404 > [WW-5700] - Failed type conversion stores the NO_CONVERSION_POSSIBLE > marker string into typed Maps, Lists and Collections > [WW-5701] - CollectionConverter silently drops a legitimate element > whose text equals the NO_CONVERSION_POSSIBLE marker > [WW-5703] - HTML5 pattern false-rejects whitespace-only input that the > regex validator accepts > [WW-5704] - HTML5 required false-rejects on radio/file when the bound > property is never null > [WW-5705] - StringIndexOutOfBoundsException authorizing a parameter name > that begins with a nesting character > [WW-5706] - RestfulActionMapper does not apply the action name > validation used by DefaultActionMapper > [WW-5711] - StringConverter does not bound fraction digits when > formatting BigDecimal > [WW-5712] - ParameterAuthorizingModule does not wrap the Jackson > any-setter in the REST plugin > [WW-5715] - REST body authorization keys off the Jackson external > property name instead of the Java member > [WW-5724] - Cached MessageFormat instances in > AbstractLocalizedTextProvider are shared between concurrent callers > [WW-5725] - AuthorizingSettableBeanProperty does not authorize the > buffered set() path in the REST plugin > [WW-5726] - Merged polymorphic property with a non-null initial value is > not authorized in the REST plugin > [WW-5727] - The @JsonIdentityInfo id property is not authorized in the > REST plugin > [WW-5729] - JasperReports plugin: ValueStackShadowMap overloads > get/containsKey instead of overriding them, so the value-stack fallback > never reaches JasperReports > [WW-5731] - JasperReport7CsvExporterProvider sets the record delimiter > to the field delimiter > [WW-5732] - JasperReport7Result Javadoc example uses upper-case format > "CSV" which fails the exporter lookup > [WW-5733] - JasperReports 7 exporter providers close the response stream > before the report is written — empty response on Tomcat > [WW-5735] - JasperReports 7 plugin bundles the LGPL jasperreports jar > into the release distribution > [WW-5745] - REST plugin authorizes a forward-referenced object-id > property at the depth where the reference resolves > [WW-5746] - Members of a bean-typed @JsonIdentityInfo id are authorized > at the enclosing path in the REST plugin > [WW-5747] - RedactionAwareDeserializer leaves the parser mid-object when > it drops a REST body object > [WW-5748] - Registering ParameterAuthorizingModule breaks unwrapped XML > lists in JacksonXmlHandler > [WW-5749] - REST XML handlers throw NullPointerException when there is > no target to render > > New Feature > [WW-5695] - Derive HTML5 constraint attributes from validators in the > html5 theme > > Improvement > [WW-1742] - new token associated execute and wait interceptor > [WW-3245] - Jasper plugin does not support supply of data via report > parameters (for example Hibernate session object) > [WW-5676] - Decide whether array and primitive types should resolve to > their element/wrapper package in OGNL security checks > [WW-5687] - Clear the conversion and validator caches on > Dispatcher.cleanup() (WW-5537 defence-in-depth follow-on) > [WW-5694] - Deprecate JavaScript client-side validation in the xhtml and > css_xhtml themes > [WW-5713] - Fail closed for legacy Tiles OGNL evaluation > [WW-5716] - Bound the per-locale definition caches in the Tiles plugin > [WW-5718] - Plugin-provided default interceptor stacks omit the > resource-isolation interceptors > [WW-5719] - Verify pinned Maven wrapper bootstrap artifacts > [WW-5720] - AuthorizingSettableAnyProperty logs one WARN per rejected > dynamic key > [WW-5723] - REST plugin does not bound the request body read in > ContentTypeInterceptor > [WW-5740] - Resolve HTML5 constraint messages for visitor-validated > fields against the visited object > [WW-5743] - ActionNameSpecificityComparator can rank a broad ** pattern > ahead of a narrower */* one > > Task > [WW-5684] - Document the SecurityMemberAccess dev-mode setter removal in > the Migration Guide > [WW-5690] - Defer loading the dev-mode error template until first use > [WW-5697] - Restrict the indexed-access fast path in XWorkMethodAccessor > to real indexed property accessors > [WW-5698] - ModelDriven exemption in StrutsParameterAuthorizer also > exempts the action's own members > [WW-5702] - Polish HTML5 constraint derivation: scope gaps and attribute > hygiene found reviewing WW-5695 > [WW-5707] - Deprecate legacy restful and restful2 action mappers in core > [WW-5709] - @StrutsParameter enforcement does not recognise fluent > (non-void) setters > [WW-5710] - Allowlist priming targets the ModelDriven model even when > the parameter was authorised on the action > [WW-5717] - Address OWASP dependency-check finding in Spring Framework > (spring-core) > [WW-5728] - Add a struts-site page for the JasperReports 7 plugin > [WW-5734] - Run the JasperReports 7 plugin end-to-end on an embedded > Tomcat in its test suite > [WW-5741] - Dismiss the CodeQL java/xss alert on > DefaultContentTypeHandlerManager.handleResult as a false positive > > Sub-task > [WW-5674] - Cut the per-call allocations in > SecurityMemberAccess.isClassBelongsToPackages > [WW-5675] - Stop re-parsing OGNL security config on every > SecurityMemberAccess instantiation > [WW-5677] - Remove the remaining redundant getPackage() lookups on the > OGNL member-access path > > Release notes: > * https://cwiki.apache.org/confluence/display/WW/Version+Notes+7.4.0 > > Github release > * https://github.com/apache/struts/releases/tag/STRUTS_7_4_0 > > Distribution: > * https://dist.apache.org/repos/dist/dev/struts/7.4.0/ > > Maven 2 staging repository: > * https://repository.apache.org/content/groups/staging/ > > Once you have had a chance to review the test build, please respond > with a vote on its quality: > > [ ] Leave at test build > [ ] Alpha > [ ] Beta > [ ] General Availability (GA) > > Everyone who has tested the build is invited to vote. Votes by PMC > members are considered binding. A vote passes if there are at least > three binding +1s and more +1s than -1s. > > The vote will remain open for at least 72 hours, longer upon request. > A vote can be amended at any time to upgrade or downgrade the quality > of the release based on future experience. If an initial vote > designates the build as "Beta", the release will be submitted for > mirroring and announced to the user list. Once released as a public > beta, subsequent quality votes on a build may be held on the user > list. > > As always, the act of voting carries certain obligations. A binding > vote not only states an opinion, but means that the voter is agreeing > to help do the work. > > On behalf of the Apache Struts project > Łukasz --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
