This is an automated email from the ASF dual-hosted git repository. rmaucher pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/tomcat.git
commit a7541464c5bcdbed11cd4fa0cf514e9a834fad2c Author: opencode <[email protected]> AuthorDate: Mon Oct 19 10:17:45 2026 +0200 Correct the assignability check for Graal bean property writes GraalBeanELResolver.getWriteMethod() accepted a setter when the parameter type was assignable from the value type, which is the reverse of what is required to invoke setX(P) with a value of type V, namely that P accepts V. As a result, any setter whose parameter type was a super-type of the value type, for example a setter taking Object or an interface, was rejected. In a GraalVM native image, where this resolver stands in for the reflection-configured BeanELResolver, EL assignments to such properties were silently dropped and the properties were reported as read only. Flip the check so the write method's parameter type is checked for assignability from the value type. The shipped test encoded the incorrect behaviour by asserting that a property with a setBla(Object) setter was read only. That assertion is flipped and a regression test is added that verifies a write through a super-type setter reaches the bean. Found by code review. --- java/org/apache/jasper/el/JasperELResolver.java | 2 +- test/org/apache/jasper/el/TestJasperELResolver.java | 16 ++++++++++++++-- webapps/docs/changelog.xml | 8 ++++++++ 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/java/org/apache/jasper/el/JasperELResolver.java b/java/org/apache/jasper/el/JasperELResolver.java index 5dd5bb35d2..641cbec7fc 100644 --- a/java/org/apache/jasper/el/JasperELResolver.java +++ b/java/org/apache/jasper/el/JasperELResolver.java @@ -274,7 +274,7 @@ public class JasperELResolver extends CompositeELResolver { Method[] methods = beanClass.getMethods(); for (Method method : methods) { if (method.getParameterCount() == 1 && setter.equals(method.getName()) && - (valueClass == null || valueClass.isAssignableFrom(method.getParameterTypes()[0]))) { + (valueClass == null || method.getParameterTypes()[0].isAssignableFrom(valueClass))) { return method; } } diff --git a/test/org/apache/jasper/el/TestJasperELResolver.java b/test/org/apache/jasper/el/TestJasperELResolver.java index 3d93d11f55..411a3ebbb8 100644 --- a/test/org/apache/jasper/el/TestJasperELResolver.java +++ b/test/org/apache/jasper/el/TestJasperELResolver.java @@ -88,7 +88,14 @@ public class TestJasperELResolver { Assert.assertNull(resolver.getValue(context, new TestBean(), "foobar")); Assert.assertNull(resolver.getValue(context, new TestBean(), "bar")); Assert.assertFalse(resolver.isReadOnly(context, new TestBean(), "foo")); - Assert.assertTrue(resolver.isReadOnly(context, new TestBean(), "bla")); + Assert.assertFalse(resolver.isReadOnly(context, new TestBean(), "bla")); + + // A setter whose parameter type is a supertype of the value type must + // be used. The inverted assignability check in getWriteMethod() + // previously rejected such setters, silently dropping the write. + TestBean bean = new TestBean(); + resolver.setValue(context, bean, "bla", "a string value"); + Assert.assertEquals("a string value", bean.getLastBla()); } public static class TestBean { @@ -108,10 +115,15 @@ public class TestJasperELResolver { public String isFoobar() { return "foobar"; } + private Object bla; public String getBla() { return "bla"; } - public void setBla(@SuppressWarnings("unused") Object bla) { + public void setBla(Object bla) { + this.bla = bla; + } + public Object getLastBla() { + return bla; } } } diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml index 30051b6b21..1b9bc526a5 100644 --- a/webapps/docs/changelog.xml +++ b/webapps/docs/changelog.xml @@ -656,6 +656,14 @@ text node from being trimmed when <code>trim</code> was <code>true</code>. (remm) </fix> + <fix> + Correct the assignability check <code>GraalBeanELResolver</code> uses + when selecting a setter for an EL value. The check was inverted, so a + setter whose parameter type was a super-type of the value type, for + example a setter taking <code>Object</code> or an interface, was + rejected and EL writes to such properties could be silently dropped + when running in a GraalVM native image. (remm) + </fix> </changelog> </subsection> <subsection name="Cluster"> --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
