You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by re...@apache.org on 2022/08/24 08:05:46 UTC

[tomcat] branch 10.0.x updated: Fix various issues with the bean resolver used for Graal

This is an automated email from the ASF dual-hosted git repository.

remm pushed a commit to branch 10.0.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git


The following commit(s) were added to refs/heads/10.0.x by this push:
     new 1394276a4b Fix various issues with the bean resolver used for Graal
1394276a4b is described below

commit 1394276a4b343993d2e54513499fed5420bdbfcd
Author: remm <re...@apache.org>
AuthorDate: Wed Aug 24 09:58:32 2022 +0200

    Fix various issues with the bean resolver used for Graal
---
 java/org/apache/jasper/el/JasperELResolver.java    | 27 +++++++++++-------
 .../org/apache/jasper/el/TestJasperELResolver.java | 32 ++++++++++++++++++++++
 webapps/docs/changelog.xml                         |  4 +++
 3 files changed, 53 insertions(+), 10 deletions(-)

diff --git a/java/org/apache/jasper/el/JasperELResolver.java b/java/org/apache/jasper/el/JasperELResolver.java
index 7c02cea430..2164dada30 100644
--- a/java/org/apache/jasper/el/JasperELResolver.java
+++ b/java/org/apache/jasper/el/JasperELResolver.java
@@ -188,7 +188,7 @@ public class JasperELResolver extends CompositeELResolver {
      * Extend ELResolver for Graal to avoid bean info use if possible,
      * as BeanELResolver needs manual reflection configuration.
      */
-    private static class GraalBeanELResolver extends ELResolver {
+    public static class GraalBeanELResolver extends ELResolver {
 
         @Override
         public Object getValue(ELContext context, Object base,
@@ -214,7 +214,7 @@ public class JasperELResolver extends CompositeELResolver {
             if (base == null) {
                 return;
             }
-            Method method = getWriteMethod(base.getClass(), property.toString());
+            Method method = getWriteMethod(base.getClass(), property.toString(), value.getClass());
             if (method != null) {
                 context.setPropertyResolved(base, property);
                 try {
@@ -231,35 +231,42 @@ public class JasperELResolver extends CompositeELResolver {
                 Object property) {
             Class<?> beanClass = base.getClass();
             String prop = property.toString();
-            return (getReadMethod(beanClass, prop) != null)
-                    && (getWriteMethod(beanClass, prop) != null);
+            Method readMethod = getReadMethod(beanClass, prop);
+            return readMethod == null || !(getWriteMethod(beanClass, prop, readMethod.getReturnType()) != null);
         }
 
-        public static Method getReadMethod(Class<?> beanClass, String prop) {
+        private static Method getReadMethod(Class<?> beanClass, String prop) {
             Method result = null;
-            String setter = "get" + capitalize(prop);
+            String getter = "get" + capitalize(prop);
             Method methods[] = beanClass.getMethods();
             for (Method method : methods) {
-                if (setter.equals(method.getName())) {
+                if (method.getParameterCount() == 0 && getter.equals(method.getName())) {
+                    return method;
+                }
+            }
+            getter = "is" + capitalize(prop);
+            for (Method method : methods) {
+                if (method.getParameterCount() == 0 && getter.equals(method.getName())) {
                     return method;
                 }
             }
             return result;
         }
 
-        public static Method getWriteMethod(Class<?> beanClass, String prop) {
+        private static Method getWriteMethod(Class<?> beanClass, String prop, Class<?> valueClass) {
             Method result = null;
             String setter = "set" + capitalize(prop);
             Method methods[] = beanClass.getMethods();
             for (Method method : methods) {
-                if (setter.equals(method.getName())) {
+                if (method.getParameterCount() == 1 && setter.equals(method.getName())
+                        && (valueClass == null || valueClass.isAssignableFrom(method.getParameterTypes()[0]))) {
                     return method;
                 }
             }
             return result;
         }
 
-        public static String capitalize(String name) {
+        private static String capitalize(String name) {
             if (name == null || name.length() == 0) {
                 return name;
             }
diff --git a/test/org/apache/jasper/el/TestJasperELResolver.java b/test/org/apache/jasper/el/TestJasperELResolver.java
index d58391ebfe..ab1d4edb32 100644
--- a/test/org/apache/jasper/el/TestJasperELResolver.java
+++ b/test/org/apache/jasper/el/TestJasperELResolver.java
@@ -21,6 +21,7 @@ import java.util.ArrayList;
 import java.util.List;
 import java.util.concurrent.atomic.AtomicInteger;
 
+import jakarta.el.ELContext;
 import jakarta.el.ELResolver;
 import jakarta.servlet.jsp.el.ImplicitObjectELResolver;
 
@@ -74,4 +75,35 @@ public class TestJasperELResolver {
         field.setAccessible(true);
         return field.get(target);
     }
+
+    @Test
+    public void testGraalResolver() throws Exception {
+        ELResolver resolver = new JasperELResolver.GraalBeanELResolver();
+        ELContext context = new ELContextImpl(resolver);
+        Assert.assertEquals("foo", resolver.getValue(context, new TestBean(), "foo"));
+        Assert.assertEquals("bla", resolver.getValue(context, new TestBean(), "bla"));
+        Assert.assertEquals("foobar", 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"));
+    }
+
+    public static class TestBean {
+        public String getFoo() {
+            return "foo";
+        }
+        public void setFoo(String foo) {
+        }
+        public String getBar(boolean i) {
+            return "bar";
+        }
+        public String isFoobar() {
+            return "foobar";
+        }
+        public String isBla() {
+            return "bla";
+        }
+        public void setBla(Object bla) {
+        }
+    }
 }
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index 06c990c816..b942d8be66 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -201,6 +201,10 @@
         so that larger values are correctly parsed to <code>BigInteger</code>
         and <code>BigDecimal</code> respectively. (markt)
       </fix>
+      <fix>
+        <bug>66235</bug>: Fix various issues with the bean resolver used for
+        Graal. (remm)
+      </fix>
     </changelog>
   </subsection>
   <subsection name="Cluster">


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org