You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by ta...@apache.org on 2026/10/04 09:56:38 UTC

(myfaces) branch 4.0.x updated: MYFACES-4766: make literal property initialization thread-safe (#1087)

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

tandraschko pushed a commit to branch 4.0.x
in repository https://gitbox.apache.org/repos/asf/myfaces.git


The following commit(s) were added to refs/heads/4.0.x by this push:
     new a1fa3e423 MYFACES-4766: make literal property initialization thread-safe (#1087)
a1fa3e423 is described below

commit a1fa3e4233214bd7504d8b6ed21b33c8ac1665ee
Author: Vicente Rossello Jaume <co...@gmail.com>
AuthorDate: Sun Oct 4 11:56:32 2026 +0200

    MYFACES-4766: make literal property initialization thread-safe (#1087)
    
    Co-authored-by: vrossello <vr...@travelcompositor.com>
---
 .../view/facelets/tag/BeanPropertyTagRule.java     | 33 +++++++++++++---------
 1 file changed, 19 insertions(+), 14 deletions(-)

diff --git a/impl/src/main/java/org/apache/myfaces/view/facelets/tag/BeanPropertyTagRule.java b/impl/src/main/java/org/apache/myfaces/view/facelets/tag/BeanPropertyTagRule.java
index 7e6231930..33de09532 100644
--- a/impl/src/main/java/org/apache/myfaces/view/facelets/tag/BeanPropertyTagRule.java
+++ b/impl/src/main/java/org/apache/myfaces/view/facelets/tag/BeanPropertyTagRule.java
@@ -22,6 +22,7 @@
 import java.lang.reflect.Method;
 import java.util.function.BiConsumer;
 
+import jakarta.faces.context.FacesContext;
 import jakarta.faces.view.facelets.FaceletContext;
 import jakarta.faces.view.facelets.MetaRule;
 import jakarta.faces.view.facelets.Metadata;
@@ -29,6 +30,8 @@
 import jakarta.faces.view.facelets.TagAttribute;
 import jakarta.faces.view.facelets.TagAttributeException;
 
+import org.apache.myfaces.util.lang.Lazy;
+
 /**
  * 
  * @author Jacob Hookom
@@ -85,8 +88,8 @@ final static class LiteralPropertyMetadata extends Metadata
         private final Method method;
         private final BiConsumer<Object, Object> function;
         private final TagAttribute attribute;
-        private Object value;
-        private Object[] valueArgs;
+        private final Lazy<Object> value;
+        private final Lazy<Object[]> valueArgs;
 
         public LiteralPropertyMetadata(Class<?> propertyType, Method method, TagAttribute attribute)
         {
@@ -94,6 +97,8 @@ public LiteralPropertyMetadata(Class<?> propertyType, Method method, TagAttribut
             this.method = method;
             this.function = null;
             this.attribute = attribute;
+            this.value = null;
+            this.valueArgs = new Lazy<>(() -> new Object[] { createValue() });
         }
         
         public LiteralPropertyMetadata(Class<?> propertyType, BiConsumer<Object, Object> function,
@@ -103,6 +108,8 @@ public LiteralPropertyMetadata(Class<?> propertyType, BiConsumer<Object, Object>
             this.method = null;
             this.function = function;
             this.attribute = attribute;
+            this.value = new Lazy<>(this::createValue);
+            this.valueArgs = null;
         }
 
         @Override
@@ -112,21 +119,11 @@ public void applyMetadata(FaceletContext ctx, Object instance)
             {
                 if (function != null)
                 {
-                    if (value == null)
-                    {
-                        String str = this.attribute.getValue();
-                        value = ctx.getExpressionFactory().coerceToType(str, propertyType);
-                    }
-                    function.accept(instance, value);
+                    function.accept(instance, value.get());
                 }
                 else if (method != null)
                 {
-                    if (valueArgs == null)
-                    {
-                        String str = this.attribute.getValue();
-                        valueArgs = new Object[] { ctx.getExpressionFactory().coerceToType(str, propertyType) };
-                    }
-                    method.invoke(instance, valueArgs);
+                    method.invoke(instance, valueArgs.get());
                 }
             }
             catch (InvocationTargetException e)
@@ -139,6 +136,14 @@ else if (method != null)
             }
         }
 
+        private Object createValue()
+        {
+            // Resolve the active context only during initialization; do not retain request state.
+            FaceletContext ctx = (FaceletContext) FacesContext.getCurrentInstance()
+                    .getAttributes().get(FaceletContext.FACELET_CONTEXT_KEY);
+            return ctx.getExpressionFactory().coerceToType(attribute.getValue(), propertyType);
+        }
+
     }
 
     final static class DynamicPropertyMetadata extends Metadata