lukaszlenart opened a new pull request, #1931: URL: https://github.com/apache/struts/pull/1931
Fixes [WW-5709](https://issues.apache.org/jira/browse/WW-5709) `java.beans.Introspector` only records a write method for a `void` setter, while OGNL binds through any public one-argument `setX` method regardless of its return type. `StrutsParameterAuthorizer` derived its view of what a target can take from `PropertyDescriptor.getWriteMethod()`, so a fluent setter was invisible to it: 1. `@StrutsParameter` on a fluent setter never counted — the parameter was rejected unless the backing field was annotated too. 2. On a `ModelDriven` action, an unannotated fluent setter on the *action* looked declared on neither the model nor the action and took the custom-accessor fallback WW-5698 left for Map-backed models, so it bound. ### Change `findBindableAccessor` resolves the depth-0 accessor the way OGNL does — from the already-cached `BeanInfo`'s method descriptors, by name and arity, public and non-static — and both `declaresProperty` and `hasValidAnnotatedMember` go through it. Depth ≥ 1 still uses the read method, so `OgnlParameterAllowlister` is untouched. Where several setters qualify, the most-derived declaration wins (an annotated override of a generic base's erased `setModel(Object)` is the one judged), and among overloads at that level an annotated one (a convenience `setAge(int)` beside `@StrutsParameter setAge(String)` no longer turns the property away — that would have been a regression against `main`). `hasValidAnnotatedPropertyDescriptor` is kept as a delegating shim, `@Deprecated(forRemoval = true)`; removal is [WW-5739](https://issues.apache.org/jira/browse/WW-5739) at 8.0.0. ### Behaviour change With `struts.parameters.requireAnnotations=true`: annotated fluent setters now bind; an unannotated fluent setter on a `ModelDriven` action is now rejected like a void one. Relative to 7.3.0 this is part of the WW-5698 change and rides on its migration note. ### Tests - `ParameterAuthorizerTest`: annotated / unannotated fluent setter, fluent setter on a `ModelDriven` action (rejected unannotated, authorized annotated), fluent setter on the model shadowing an unannotated action setter, static `setX` namesake (still no exemption — proven load-bearing), generic-override and same-class-overload preference. - `ParametersInterceptorTest.testModelDrivenFluentSetterOnActionRequiresAnnotation`: end-to-end through the real OGNL stack; RED on `main` (`secret` bound through the fluent setter), paired with two positive binds so the negative is not vacuous. `core`, `plugins/json`, `plugins/rest` test suites pass. 🤖 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]
