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

lukaszlenart pushed a commit to branch 
fix/WW-5368-label-ognl-security-warning-research
in repository https://gitbox.apache.org/repos/asf/struts.git

commit 55930d20f384b681e19b1f335a00c8270f51948e
Author: Lukasz Lenart <[email protected]>
AuthorDate: Sun Nov 23 13:05:16 2025 +0100

    fix(core): WW-5368 eliminate OGNL warnings for component field access
    
    Change UIBean and related component fields from protected to private
    with public getters to prevent false-positive OGNL SecurityMemberAccess
    warnings when evaluating expressions with resource bundle keys.
    
    Previously, expressions like getText('label.key.'+top) would trigger
    warnings: "Access to non-public [protected String UIBean.label] is blocked!"
    because OGNL attempted to access protected fields directly.
    
    Changes:
    - UIBean: Changed label, name, value, id fields to private, added getters
    - Bean, Param, Text, I18n: Changed name/value fields to private, added 
getters
    - Updated all subclasses to use getters instead of direct field access
    - Added test to verify OGNL can access fields via public getters
    
    Fixes #WW-5368
    
    🤖 Generated with [Claude Code](https://claude.com/claude-code)
    
    Co-Authored-By: Claude <[email protected]>
---
 .../java/org/apache/struts2/components/Bean.java   |  25 ++-
 .../java/org/apache/struts2/components/Form.java   |  22 +--
 .../org/apache/struts2/components/FormButton.java  |  14 +-
 .../java/org/apache/struts2/components/I18n.java   |  52 +++---
 .../java/org/apache/struts2/components/Label.java  |  22 +--
 .../java/org/apache/struts2/components/Param.java  |  36 +++-
 .../java/org/apache/struts2/components/Reset.java  |  23 ++-
 .../struts2/components/ServletUrlRenderer.java     |  16 +-
 .../java/org/apache/struts2/components/Submit.java |  31 ++--
 .../java/org/apache/struts2/components/Text.java   |  35 ++--
 .../java/org/apache/struts2/components/Token.java  |  16 +-
 .../java/org/apache/struts2/components/UIBean.java | 183 ++++++++++++---------
 .../org/apache/struts2/components/UIBeanTest.java  |  62 ++++++-
 13 files changed, 328 insertions(+), 209 deletions(-)

diff --git a/core/src/main/java/org/apache/struts2/components/Bean.java 
b/core/src/main/java/org/apache/struts2/components/Bean.java
index db39cb16f..8aae1c1f8 100644
--- a/core/src/main/java/org/apache/struts2/components/Bean.java
+++ b/core/src/main/java/org/apache/struts2/components/Bean.java
@@ -18,11 +18,11 @@
  */
 package org.apache.struts2.components;
 
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
 import org.apache.struts2.ObjectFactory;
 import org.apache.struts2.inject.Inject;
 import org.apache.struts2.util.ValueStack;
-import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.LogManager;
 import org.apache.struts2.util.reflection.ReflectionProvider;
 import org.apache.struts2.views.annotations.StrutsTag;
 import org.apache.struts2.views.annotations.StrutsTagAttribute;
@@ -36,10 +36,10 @@ import java.io.Writer;
  *
  * <p>If the var attribute is set on the BeanTag, it will place the 
instantiated bean into the
  * stack's Context.</p>
- *
+ * <p>
  * <!-- END SNIPPET: javadoc -->
- *
- *
+ * <p>
+ * <p>
  * <!-- START SNIPPET: params -->
  * <ul>
  *      <li>var - the stack's context name (if supplied) that the created bean 
will be store under</li>
@@ -65,8 +65,8 @@ import java.io.Writer;
  * &lt;/s:bean&gt;
  * <!-- END SNIPPET: examples -->
  * </pre>
- *
- *
+ * <p>
+ * <p>
  * <!-- START SNIPPET: examplesdescription -->
  * <p>This example instantiates a bean called SimpleCounter and sets the foo 
property (setFoo('BAR')). The
  * SimpleCounter object is then pushed onto the Valuestack, which means that 
we can call its accessor methods (getFoo())
@@ -95,7 +95,7 @@ public class Bean extends ContextBean {
     protected static final Logger LOG = LogManager.getLogger(Bean.class);
 
     protected Object bean;
-    protected String name;
+    private String name;
     protected ObjectFactory objectFactory;
     protected ReflectionProvider reflectionProvider;
 
@@ -146,6 +146,15 @@ public class Bean extends ContextBean {
         reflectionProvider.setProperty(key, value, bean, 
getStack().getContext());
     }
 
+    /**
+     * Gets the class name of the bean to be instantiated.
+     *
+     * @return the class name
+     */
+    public String getName() {
+        return name;
+    }
+
     @StrutsTagAttribute(description = "The class name of the bean to be 
instantiated (must respect JavaBean specification)", required = true)
     public void setName(String name) {
         this.name = name;
diff --git a/core/src/main/java/org/apache/struts2/components/Form.java 
b/core/src/main/java/org/apache/struts2/components/Form.java
index 7db1477c3..46f6b87fa 100644
--- a/core/src/main/java/org/apache/struts2/components/Form.java
+++ b/core/src/main/java/org/apache/struts2/components/Form.java
@@ -18,11 +18,15 @@
  */
 package org.apache.struts2.components;
 
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
+import org.apache.commons.lang3.StringUtils;
 import org.apache.struts2.ObjectFactory;
 import org.apache.struts2.config.Configuration;
 import org.apache.struts2.config.RuntimeConfiguration;
 import org.apache.struts2.config.entities.ActionConfig;
 import org.apache.struts2.config.entities.InterceptorMapping;
+import org.apache.struts2.dispatcher.mapper.ActionMapping;
 import org.apache.struts2.inject.Inject;
 import org.apache.struts2.interceptor.MethodFilterInterceptorUtil;
 import org.apache.struts2.util.ValueStack;
@@ -33,10 +37,6 @@ import org.apache.struts2.validator.ValidationInterceptor;
 import org.apache.struts2.validator.Validator;
 import org.apache.struts2.validator.ValidatorContext;
 import org.apache.struts2.validator.validators.VisitorFieldValidator;
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.struts2.dispatcher.mapper.ActionMapping;
 import org.apache.struts2.views.annotations.StrutsTag;
 import org.apache.struts2.views.annotations.StrutsTagAttribute;
 
@@ -90,10 +90,10 @@ import java.util.Set;
  * </pre>
  */
 @StrutsTag(
-    name = "form",
-    tldTagClass = "org.apache.struts2.views.jsp.ui.FormTag",
-    description = "Renders an input form",
-    allowDynamicAttributes = true)
+        name = "form",
+        tldTagClass = "org.apache.struts2.views.jsp.ui.FormTag",
+        description = "Renders an input form",
+        allowDynamicAttributes = true)
 public class Form extends ClosingUIBean {
     public static final String OPEN_TEMPLATE = "form";
     public static final String TEMPLATE = "form-close";
@@ -170,7 +170,7 @@ public class Form extends ClosingUIBean {
             addParameter("validate", findValue(validate, Boolean.class));
         }
 
-        if (name == null) {
+        if (getName() == null) {
             //make the name the same as the id
             String id = (String) getAttributes().get("id");
             if (StringUtils.isNotEmpty(id)) {
@@ -223,7 +223,7 @@ public class Form extends ClosingUIBean {
      */
     @Override
     protected void populateComponentHtmlId(Form form) {
-        if (id != null) {
+        if (getId() != null) {
             super.populateComponentHtmlId(null);
         }
 
@@ -508,7 +508,7 @@ public class Form extends ClosingUIBean {
     }
 
     @StrutsTagAttribute(description = "Whether client side/remote validation 
should be performed. Only" +
-        " useful with theme xhtml/ajax", type = "Boolean", defaultValue = 
"false")
+            " useful with theme xhtml/ajax", type = "Boolean", defaultValue = 
"false")
     public void setValidate(String validate) {
         this.validate = validate;
     }
diff --git a/core/src/main/java/org/apache/struts2/components/FormButton.java 
b/core/src/main/java/org/apache/struts2/components/FormButton.java
index d46828db5..02ac884f4 100644
--- a/core/src/main/java/org/apache/struts2/components/FormButton.java
+++ b/core/src/main/java/org/apache/struts2/components/FormButton.java
@@ -18,10 +18,10 @@
  */
 package org.apache.struts2.components;
 
-import org.apache.struts2.util.ValueStack;
 import jakarta.servlet.http.HttpServletRequest;
 import jakarta.servlet.http.HttpServletResponse;
 import org.apache.struts2.dispatcher.mapper.ActionMapping;
+import org.apache.struts2.util.ValueStack;
 import org.apache.struts2.views.annotations.StrutsTagAttribute;
 
 /**
@@ -54,7 +54,7 @@ public abstract class FormButton extends ClosingUIBean {
 
         addParameter("type", submitType);
 
-        if (!BUTTON_TYPE_INPUT.equals(submitType) && (label == null)) {
+        if (!BUTTON_TYPE_INPUT.equals(submitType) && (getLabel() == null)) {
             addParameter("label", getAttributes().get("nameValue"));
         }
 
@@ -94,15 +94,15 @@ public abstract class FormButton extends ClosingUIBean {
      */
     protected void populateComponentHtmlId(Form form) {
         String tmpId = "";
-        if (id != null) {
+        if (getId() != null) {
             // this check is needed for backwards compatibility with 2.1.x
-            tmpId = findString(id);
+            tmpId = findString(getId());
         } else {
             if (form != null && form.getAttributes().get("id") != null) {
                 tmpId = tmpId + form.getAttributes().get("id").toString() + 
"_";
             }
-            if (name != null) {
-                tmpId = tmpId + escape(findString(name));
+            if (getName() != null) {
+                tmpId = tmpId + escape(findString(getName()));
             } else if (action != null || method != null) {
                 if (action != null) {
                     tmpId = tmpId + escape(findString(action));
@@ -141,7 +141,7 @@ public abstract class FormButton extends ClosingUIBean {
 
 
     @StrutsTagAttribute(description = "The type of submit to use. Valid values 
are <i>input</i>, " +
-        "<i>button</i> and <i>image</i>.", defaultValue = "input")
+            "<i>button</i> and <i>image</i>.", defaultValue = "input")
     public void setType(String type) {
         this.type = type;
     }
diff --git a/core/src/main/java/org/apache/struts2/components/I18n.java 
b/core/src/main/java/org/apache/struts2/components/I18n.java
index 64e002a36..1c418d463 100644
--- a/core/src/main/java/org/apache/struts2/components/I18n.java
+++ b/core/src/main/java/org/apache/struts2/components/I18n.java
@@ -18,38 +18,37 @@
  */
 package org.apache.struts2.components;
 
-import java.io.Writer;
-import java.util.ResourceBundle;
-
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.apache.struts2.StrutsException;
+import org.apache.struts2.inject.Inject;
+import org.apache.struts2.locale.LocaleProvider;
 import org.apache.struts2.locale.LocaleProviderFactory;
 import org.apache.struts2.text.LocalizedTextProvider;
+import org.apache.struts2.text.TextProvider;
 import org.apache.struts2.text.TextProviderFactory;
+import org.apache.struts2.util.ValueStack;
 import org.apache.struts2.views.annotations.StrutsTag;
 import org.apache.struts2.views.annotations.StrutsTagAttribute;
-import org.apache.struts2.StrutsException;
 
-import org.apache.struts2.locale.LocaleProvider;
-import org.apache.struts2.text.TextProvider;
-import org.apache.struts2.inject.Inject;
-import org.apache.struts2.util.ValueStack;
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
+import java.io.Writer;
+import java.util.ResourceBundle;
 
 /**
  * <!-- START SNIPPET: javadoc -->
- *
+ * <p>
  * Gets a resource bundle and place it on the value stack. This allows
  * the text tag to access messages from any bundle, and not just the bundle
  * associated with the current action.
- *
+ * <p>
  * <!-- END SNIPPET: javadoc -->
- *
+ * <p>
  * <!-- START SNIPPET: params-->
  *
  * <ul>
  *      <li>name* - the resource bundle's name (eg foo/bar/customBundle)</li>
  * </ul>
- *
+ * <p>
  * <!-- END SNIPPET: params -->
  *
  * <p>
@@ -78,14 +77,14 @@ import org.apache.logging.log4j.Logger;
  * </pre>
  *
  */
-@StrutsTag(name="i18n", tldTagClass="org.apache.struts2.views.jsp.I18nTag", 
description="Get a resource bundle" +
-                " and place it on the value stack")
+@StrutsTag(name = "i18n", tldTagClass = 
"org.apache.struts2.views.jsp.I18nTag", description = "Get a resource bundle" +
+        " and place it on the value stack")
 public class I18n extends Component {
 
     private static final Logger LOG = LogManager.getLogger(I18n.class);
 
     protected boolean pushed;
-    protected String name;
+    private String name;
 
     private LocalizedTextProvider localizedTextProvider;
     private TextProvider textProvider;
@@ -145,17 +144,26 @@ public class I18n extends Component {
         if (pushed) {
             Object o = getStack().pop();
             if ((o == null) || (!o.equals(textProvider))) {
-                LOG.error("A closing i18n tag attempted to pop its own 
TextProvider from the top of the ValueStack but popped an unexpected object 
("+(o != null ? o.getClass() : "null")+"). " +
-                            "Refactor the page within the i18n tags to ensure 
no objects are pushed onto the ValueStack without popping them prior to the 
closing tag. " +
-                            "If you see this message it's likely that the 
i18n's TextProvider is still on the stack and will continue to provide message 
resources after the closing tag.");
-                throw new StrutsException("A closing i18n tag attempted to pop 
its TextProvider from the top of the ValueStack but popped an unexpected object 
("+(o != null ? o.getClass() : "null")+")");
+                LOG.error("A closing i18n tag attempted to pop its own 
TextProvider from the top of the ValueStack but popped an unexpected object (" 
+ (o != null ? o.getClass() : "null") + "). " +
+                        "Refactor the page within the i18n tags to ensure no 
objects are pushed onto the ValueStack without popping them prior to the 
closing tag. " +
+                        "If you see this message it's likely that the i18n's 
TextProvider is still on the stack and will continue to provide message 
resources after the closing tag.");
+                throw new StrutsException("A closing i18n tag attempted to pop 
its TextProvider from the top of the ValueStack but popped an unexpected object 
(" + (o != null ? o.getClass() : "null") + ")");
             }
         }
 
         return super.end(writer, body);
     }
 
-    @StrutsTagAttribute(description="Name of resource bundle to use (eg 
foo/bar/customBundle)", required=true, defaultValue="String")
+    /**
+     * Gets the name of the resource bundle to use.
+     *
+     * @return the resource bundle name
+     */
+    public String getName() {
+        return name;
+    }
+
+    @StrutsTagAttribute(description = "Name of resource bundle to use (eg 
foo/bar/customBundle)", required = true, defaultValue = "String")
     public void setName(String name) {
         this.name = name;
     }
diff --git a/core/src/main/java/org/apache/struts2/components/Label.java 
b/core/src/main/java/org/apache/struts2/components/Label.java
index 52ba02ac7..5f813d886 100644
--- a/core/src/main/java/org/apache/struts2/components/Label.java
+++ b/core/src/main/java/org/apache/struts2/components/Label.java
@@ -18,10 +18,10 @@
  */
 package org.apache.struts2.components;
 
-import org.apache.struts2.util.ValueStack;
 import jakarta.servlet.http.HttpServletRequest;
 import jakarta.servlet.http.HttpServletResponse;
 import org.apache.struts2.util.TextProviderHelper;
+import org.apache.struts2.util.ValueStack;
 import org.apache.struts2.views.annotations.StrutsTag;
 import org.apache.struts2.views.annotations.StrutsTagAttribute;
 
@@ -32,7 +32,7 @@ import 
org.apache.struts2.views.annotations.StrutsTagAttribute;
  * <!-- END SNIPPET: javadoc -->
  *
  * <p><b>Examples</b></p>
- *
+ * <p>
  * <!-- START SNIPPET: exdescription -->
  * <p>In this example, a label is rendered. The label is retrieved from a 
ResourceBundle via the key attribute
  * giving you an output of 'User Name: Ford.Prefect'. Assuming that i18n 
message userName corresponds
@@ -51,10 +51,10 @@ import 
org.apache.struts2.views.annotations.StrutsTagAttribute;
  *
  */
 @StrutsTag(
-    name="label",
-    tldTagClass="org.apache.struts2.views.jsp.ui.LabelTag",
-    description="Render a label that displays read-only information",
-    allowDynamicAttributes=true)
+        name = "label",
+        tldTagClass = "org.apache.struts2.views.jsp.ui.LabelTag",
+        description = "Render a label that displays read-only information",
+        allowDynamicAttributes = true)
 public class Label extends UIBean {
     final public static String TEMPLATE = "label";
 
@@ -76,8 +76,8 @@ public class Label extends UIBean {
         }
 
         // try value, then key, then name (this overrides the default behavior 
in the superclass)
-        if (value != null) {
-            addParameter("nameValue", findString(value));
+        if (getValue() != null) {
+            addParameter("nameValue", findString(getValue()));
         } else if (key != null) {
             Object nameValue = attributes.get("nameValue");
             if (nameValue == null || nameValue.toString().isEmpty()) {
@@ -85,13 +85,13 @@ public class Label extends UIBean {
                 String providedLabel = TextProviderHelper.getText(key, key, 
stack);
                 addParameter("nameValue", providedLabel);
             }
-        } else if (name != null) {
-            String expr = completeExpression(name);
+        } else if (getName() != null) {
+            String expr = completeExpression(getName());
             addParameter("nameValue", findString(expr));
         }
     }
 
-    @StrutsTagAttribute(description=" HTML for attribute")
+    @StrutsTagAttribute(description = " HTML for attribute")
     public void setFor(String forAttr) {
         this.forAttr = forAttr;
     }
diff --git a/core/src/main/java/org/apache/struts2/components/Param.java 
b/core/src/main/java/org/apache/struts2/components/Param.java
index 6fcd70a2e..8c4b336f8 100644
--- a/core/src/main/java/org/apache/struts2/components/Param.java
+++ b/core/src/main/java/org/apache/struts2/components/Param.java
@@ -18,9 +18,9 @@
  */
 package org.apache.struts2.components;
 
-import org.apache.struts2.util.ValueStack;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.struts2.StrutsException;
+import org.apache.struts2.util.ValueStack;
 import org.apache.struts2.views.annotations.StrutsTag;
 import org.apache.struts2.views.annotations.StrutsTagAttribute;
 
@@ -102,17 +102,16 @@ import java.io.Writer;
  * </pre>
  * <!-- END SNIPPET: example2 -->
  *
- *
  * @see Include
  * @see Bean
  * @see Text
  *
  */
-@StrutsTag(name="param", tldTagClass="org.apache.struts2.views.jsp.ParamTag", 
description="Parametrize other tags")
+@StrutsTag(name = "param", tldTagClass = 
"org.apache.struts2.views.jsp.ParamTag", description = "Parametrize other tags")
 public class Param extends Component {
 
-    protected String name;
-    protected String value;
+    private String name;
+    private String value;
     protected boolean suppressEmptyParameters;
 
     public Param(ValueStack stack) {
@@ -170,17 +169,35 @@ public class Param extends Component {
         return true;
     }
 
-    @StrutsTagAttribute(description="Name of Parameter to set")
+    /**
+     * Gets the name of the parameter.
+     *
+     * @return the parameter name
+     */
+    public String getName() {
+        return name;
+    }
+
+    @StrutsTagAttribute(description = "Name of Parameter to set")
     public void setName(String name) {
         this.name = name;
     }
 
-    @StrutsTagAttribute(description="Value expression for Parameter to set", 
defaultValue="The value of evaluating provided name against stack")
+    /**
+     * Gets the value expression for the parameter.
+     *
+     * @return the value expression
+     */
+    public String getValue() {
+        return value;
+    }
+
+    @StrutsTagAttribute(description = "Value expression for Parameter to set", 
defaultValue = "The value of evaluating provided name against stack")
     public void setValue(String value) {
         this.value = value;
     }
 
-    @StrutsTagAttribute(description="Whether to suppress empty parameters", 
type="Boolean", defaultValue="false")
+    @StrutsTagAttribute(description = "Whether to suppress empty parameters", 
type = "Boolean", defaultValue = "false")
     public void setSuppressEmptyParameters(boolean suppressEmptyParameters) {
         this.suppressEmptyParameters = suppressEmptyParameters;
     }
@@ -198,7 +215,8 @@ public class Param extends Component {
 
         /**
          * Adds the given value as a parameter to the outer tag.
-         * @param value  the value
+         *
+         * @param value the value
          */
         void addParameter(Object value);
     }
diff --git a/core/src/main/java/org/apache/struts2/components/Reset.java 
b/core/src/main/java/org/apache/struts2/components/Reset.java
index c1ec34ca2..dea9c3330 100644
--- a/core/src/main/java/org/apache/struts2/components/Reset.java
+++ b/core/src/main/java/org/apache/struts2/components/Reset.java
@@ -18,13 +18,12 @@
  */
 package org.apache.struts2.components;
 
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
 import org.apache.struts2.util.ValueStack;
 import org.apache.struts2.views.annotations.StrutsTag;
 import org.apache.struts2.views.annotations.StrutsTagAttribute;
 
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
-
 /**
  * <!-- START SNIPPET: javadoc -->
  * Render a reset button. The reset tag is used together with the form tag to 
provide form resetting.
@@ -54,10 +53,10 @@ import jakarta.servlet.http.HttpServletResponse;
  *
  */
 @StrutsTag(
-    name="reset",
-    tldTagClass="org.apache.struts2.views.jsp.ui.ResetTag",
-    description="Render a reset button",
-    allowDynamicAttributes=true)
+        name = "reset",
+        tldTagClass = "org.apache.struts2.views.jsp.ui.ResetTag",
+        description = "Render a reset button",
+        allowDynamicAttributes = true)
 public class Reset extends FormButton {
     final public static String TEMPLATE = "reset";
 
@@ -82,8 +81,8 @@ public class Reset extends FormButton {
     }
 
     public void evaluateParams() {
-        if (value == null) {
-            value = (key != null ? "%{getText('"+key+"')}" : "Reset");
+        if (getValue() == null) {
+            setValue(key != null ? "%{getText('" + key + "')}" : "Reset");
         }
         super.evaluateParams();
     }
@@ -97,13 +96,13 @@ public class Reset extends FormButton {
         return false;
     }
 
-    @StrutsTagAttribute(description="Supply a reset button text apart from 
reset value. Will have no effect for " +
-                "<i>input</i> type reset, since button text will always be the 
value parameter.")
+    @StrutsTagAttribute(description = "Supply a reset button text apart from 
reset value. Will have no effect for " +
+            "<i>input</i> type reset, since button text will always be the 
value parameter.")
     public void setLabel(String label) {
         super.setLabel(label);
     }
 
-    @StrutsTagAttribute(description="Supply an image src for <i>image</i> type 
reset button. Will have no effect for types <i>input</i> and <i>button</i>.")
+    @StrutsTagAttribute(description = "Supply an image src for <i>image</i> 
type reset button. Will have no effect for types <i>input</i> and 
<i>button</i>.")
     public void setSrc(String src) {
         this.src = src;
     }
diff --git 
a/core/src/main/java/org/apache/struts2/components/ServletUrlRenderer.java 
b/core/src/main/java/org/apache/struts2/components/ServletUrlRenderer.java
index c6bfec306..37928a41a 100644
--- a/core/src/main/java/org/apache/struts2/components/ServletUrlRenderer.java
+++ b/core/src/main/java/org/apache/struts2/components/ServletUrlRenderer.java
@@ -18,19 +18,19 @@
  */
 package org.apache.struts2.components;
 
-import org.apache.struts2.ActionContext;
-import org.apache.struts2.ActionInvocation;
-import org.apache.struts2.config.entities.ActionConfig;
-import org.apache.struts2.inject.Inject;
-import org.apache.struts2.util.ValueStack;
 import jakarta.servlet.RequestDispatcher;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
+import org.apache.struts2.ActionContext;
+import org.apache.struts2.ActionInvocation;
 import org.apache.struts2.StrutsException;
+import org.apache.struts2.config.entities.ActionConfig;
 import org.apache.struts2.dispatcher.mapper.ActionMapper;
 import org.apache.struts2.dispatcher.mapper.ActionMapping;
+import org.apache.struts2.inject.Inject;
 import org.apache.struts2.url.QueryStringParser;
+import org.apache.struts2.util.ValueStack;
 import org.apache.struts2.views.util.UrlHelper;
 
 import java.io.IOException;
@@ -172,12 +172,12 @@ public class ServletUrlRenderer implements UrlRenderer {
         String actionMethod = nameMapping.getMethod();
 
         final ActionConfig actionConfig = 
formComponent.configuration.getRuntimeConfiguration().getActionConfig(
-            namespace, actionName);
+                namespace, actionName);
         if (actionConfig != null) {
 
             ActionMapping mapping = new ActionMapping(actionName, namespace, 
actionMethod, formComponent.attributes);
             String result = 
urlHelper.buildUrl(formComponent.actionMapper.getUriFromActionMapping(mapping),
-                formComponent.request, formComponent.response, 
queryStringResult.getQueryParams(), scheme, formComponent.includeContext, true, 
false, false);
+                    formComponent.request, formComponent.response, 
queryStringResult.getQueryParams(), scheme, formComponent.includeContext, true, 
false, false);
             formComponent.addParameter("action", result);
 
             // let's try to get the actual action class and name
@@ -193,7 +193,7 @@ public class ServletUrlRenderer implements UrlRenderer {
             formComponent.addParameter("namespace", namespace);
 
             // if the name isn't specified, use the action name
-            if (formComponent.name == null) {
+            if (formComponent.getName() == null) {
                 formComponent.addParameter("name", actionName);
             }
 
diff --git a/core/src/main/java/org/apache/struts2/components/Submit.java 
b/core/src/main/java/org/apache/struts2/components/Submit.java
index 47024e99c..14f607df4 100644
--- a/core/src/main/java/org/apache/struts2/components/Submit.java
+++ b/core/src/main/java/org/apache/struts2/components/Submit.java
@@ -18,17 +18,15 @@
  */
 package org.apache.struts2.components;
 
-import java.io.Writer;
-
 import jakarta.servlet.http.HttpServletRequest;
 import jakarta.servlet.http.HttpServletResponse;
-
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.apache.struts2.util.ValueStack;
 import org.apache.struts2.views.annotations.StrutsTag;
 import org.apache.struts2.views.annotations.StrutsTagAttribute;
 
-import org.apache.struts2.util.ValueStack;
-import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.LogManager;
+import java.io.Writer;
 
 /**
  * <!-- START SNIPPET: javadoc -->
@@ -44,10 +42,10 @@ import org.apache.logging.log4j.LogManager;
  * <!-- END SNIPPET: javadoc -->
  */
 @StrutsTag(
-    name="submit",
-    tldTagClass="org.apache.struts2.views.jsp.ui.SubmitTag",
-    description="Render a submit button",
-    allowDynamicAttributes=true)
+        name = "submit",
+        tldTagClass = "org.apache.struts2.views.jsp.ui.SubmitTag",
+        description = "Render a submit button",
+        allowDynamicAttributes = true)
 public class Submit extends FormButton {
 
     private static final Logger LOG = LogManager.getLogger(Submit.class);
@@ -68,12 +66,12 @@ public class Submit extends FormButton {
     }
 
     public void evaluateParams() {
-        if ((key == null) && (value == null)) {
-            value = "Submit";
+        if ((key == null) && (getValue() == null)) {
+            setValue("Submit");
         }
 
-        if ((key != null) && (value == null)) {
-            this.value = "%{getText('"+key +"')}";
+        if ((key != null) && (getValue() == null)) {
+            setValue("%{getText('" + key + "')}");
         }
 
         super.evaluateParams();
@@ -98,7 +96,7 @@ public class Submit extends FormButton {
         return true;
     }
 
-    @StrutsTagAttribute(description="Supply an image src for <i>image</i> type 
submit button. Will have no effect for types <i>input</i> and <i>button</i>.")
+    @StrutsTagAttribute(description = "Supply an image src for <i>image</i> 
type submit button. Will have no effect for types <i>input</i> and 
<i>button</i>.")
     public void setSrc(String src) {
         this.src = src;
     }
@@ -124,8 +122,7 @@ public class Submit extends FormButton {
             mergeTemplate(writer, buildTemplateName(template, 
getDefaultTemplate()));
         } catch (Exception e) {
             LOG.error("error when rendering", e);
-        }
-        finally {
+        } finally {
             popComponentStack();
         }
 
diff --git a/core/src/main/java/org/apache/struts2/components/Text.java 
b/core/src/main/java/org/apache/struts2/components/Text.java
index 4f9ea316d..5d1f69a35 100644
--- a/core/src/main/java/org/apache/struts2/components/Text.java
+++ b/core/src/main/java/org/apache/struts2/components/Text.java
@@ -18,12 +18,12 @@
  */
 package org.apache.struts2.components;
 
-import org.apache.struts2.util.ValueStack;
-import org.apache.commons.text.StringEscapeUtils;
 import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.text.StringEscapeUtils;
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
 import org.apache.struts2.util.TextProviderHelper;
+import org.apache.struts2.util.ValueStack;
 import org.apache.struts2.views.annotations.StrutsTag;
 import org.apache.struts2.views.annotations.StrutsTagAttribute;
 
@@ -59,7 +59,7 @@ import java.util.List;
  * action context (action scope).
  * </p>
  * <!-- END SNIPPET: javadoc -->
- *
+ * <p>
  * <!-- START SNIPPET: params -->
  *
  * <ul>
@@ -69,13 +69,13 @@ import java.util.List;
  *      <li>escapeXml (Boolean) - Escape XML. Defaults to false</li>
  *      <li>escapeCsv (Boolean) - Escape CSV. Defaults to false</li>
  * </ul>
- *
+ * <p>
  * <!-- END SNIPPET: params -->
  *
  * <p>
  * Example:
  * </p>
- *
+ * <p>
  * <!-- START SNIPPET: exdescription -->
  * <p>Accessing messages from a given bundle (the i18n Shop example bundle in 
the first example) and using bundle defined through the framework in the second 
example.</p>
  * <!-- END SNIPPET: exdescription -->
@@ -118,16 +118,16 @@ import java.util.List;
  *
  */
 @StrutsTag(
-    name="text",
-    tldTagClass="org.apache.struts2.views.jsp.TextTag",
-    description="Render a I18n text message")
+        name = "text",
+        tldTagClass = "org.apache.struts2.views.jsp.TextTag",
+        description = "Render a I18n text message")
 public class Text extends ContextBean implements Param.UnnamedParametric {
 
     private static final Logger LOG = LogManager.getLogger(Text.class);
 
     protected List<Object> values = Collections.emptyList();
     protected String actualName;
-    protected String name;
+    private String name;
     private boolean escapeHtml = false;
     private boolean escapeJavaScript = false;
     private boolean escapeXml = false;
@@ -137,27 +137,36 @@ public class Text extends ContextBean implements 
Param.UnnamedParametric {
         super(stack);
     }
 
+    /**
+     * Gets the name of the resource property to fetch.
+     *
+     * @return the resource property name
+     */
+    public String getName() {
+        return name;
+    }
+
     @StrutsTagAttribute(description = "Name of resource property to fetch", 
required = true)
     public void setName(String name) {
         this.name = name;
     }
 
-    @StrutsTagAttribute(description="Whether to escape HTML", type="Boolean", 
defaultValue="false")
+    @StrutsTagAttribute(description = "Whether to escape HTML", type = 
"Boolean", defaultValue = "false")
     public void setEscapeHtml(boolean escape) {
         this.escapeHtml = escape;
     }
 
-    @StrutsTagAttribute(description="Whether to escape Javascript", 
type="Boolean", defaultValue="false")
+    @StrutsTagAttribute(description = "Whether to escape Javascript", type = 
"Boolean", defaultValue = "false")
     public void setEscapeJavaScript(boolean escapeJavaScript) {
         this.escapeJavaScript = escapeJavaScript;
     }
 
-    @StrutsTagAttribute(description="Whether to escape XML", type="Boolean", 
defaultValue="false")
+    @StrutsTagAttribute(description = "Whether to escape XML", type = 
"Boolean", defaultValue = "false")
     public void setEscapeXml(boolean escapeXml) {
         this.escapeXml = escapeXml;
     }
 
-    @StrutsTagAttribute(description="Whether to escape CSV (useful to escape a 
value for a column)", type="Boolean", defaultValue="false")
+    @StrutsTagAttribute(description = "Whether to escape CSV (useful to escape 
a value for a column)", type = "Boolean", defaultValue = "false")
     public void setEscapeCsv(boolean escapeCsv) {
         this.escapeCsv = escapeCsv;
     }
diff --git a/core/src/main/java/org/apache/struts2/components/Token.java 
b/core/src/main/java/org/apache/struts2/components/Token.java
index e5bc6a2ba..59a3cc5a4 100644
--- a/core/src/main/java/org/apache/struts2/components/Token.java
+++ b/core/src/main/java/org/apache/struts2/components/Token.java
@@ -18,15 +18,13 @@
  */
 package org.apache.struts2.components;
 
-import java.util.Map;
-
 import jakarta.servlet.http.HttpServletRequest;
 import jakarta.servlet.http.HttpServletResponse;
-
-import org.apache.struts2.views.annotations.StrutsTag;
 import org.apache.struts2.util.TokenHelper;
-
 import org.apache.struts2.util.ValueStack;
+import org.apache.struts2.views.annotations.StrutsTag;
+
+import java.util.Map;
 
 /**
  * <!-- START SNIPPET: javadoc -->
@@ -50,7 +48,7 @@ import org.apache.struts2.util.ValueStack;
  * @see org.apache.struts2.interceptor.TokenSessionStoreInterceptor
  *
  */
-@StrutsTag(name="token", 
tldTagClass="org.apache.struts2.views.jsp.ui.TokenTag", description="Stop 
double-submission of forms")
+@StrutsTag(name = "token", tldTagClass = 
"org.apache.struts2.views.jsp.ui.TokenTag", description = "Stop 
double-submission of forms")
 public class Token extends UIBean {
 
     public static final String TEMPLATE = "token";
@@ -78,13 +76,13 @@ public class Token extends UIBean {
         if (parameters.containsKey("name")) {
             tokenName = (String) parameters.get("name");
         } else {
-            if (name == null) {
+            if (getName() == null) {
                 tokenName = TokenHelper.DEFAULT_TOKEN_NAME;
             } else {
-                tokenName = findString(name);
+                tokenName = findString(getName());
 
                 if (tokenName == null) {
-                    tokenName = name;
+                    tokenName = getName();
                 }
             }
 
diff --git a/core/src/main/java/org/apache/struts2/components/UIBean.java 
b/core/src/main/java/org/apache/struts2/components/UIBean.java
index adac94dba..985103961 100644
--- a/core/src/main/java/org/apache/struts2/components/UIBean.java
+++ b/core/src/main/java/org/apache/struts2/components/UIBean.java
@@ -18,13 +18,8 @@
  */
 package org.apache.struts2.components;
 
-import org.apache.struts2.config.ConfigurationException;
-import org.apache.struts2.inject.Inject;
-import org.apache.struts2.util.TextParseUtil;
-import org.apache.struts2.util.ValueStack;
 import jakarta.servlet.http.HttpServletRequest;
 import jakarta.servlet.http.HttpServletResponse;
-import jakarta.servlet.http.HttpSession;
 import org.apache.commons.lang3.ObjectUtils;
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
@@ -34,11 +29,15 @@ import org.apache.struts2.components.template.Template;
 import org.apache.struts2.components.template.TemplateEngine;
 import org.apache.struts2.components.template.TemplateEngineManager;
 import org.apache.struts2.components.template.TemplateRenderingContext;
+import org.apache.struts2.config.ConfigurationException;
 import org.apache.struts2.dispatcher.AttributeMap;
 import org.apache.struts2.dispatcher.StaticContentLoader;
+import org.apache.struts2.inject.Inject;
 import org.apache.struts2.interceptor.csp.CspNonceReader;
 import org.apache.struts2.util.ComponentUtils;
+import org.apache.struts2.util.TextParseUtil;
 import org.apache.struts2.util.TextProviderHelper;
+import org.apache.struts2.util.ValueStack;
 import org.apache.struts2.views.annotations.StrutsTagAttribute;
 import org.apache.struts2.views.util.ContextUtil;
 
@@ -105,9 +104,9 @@ import static 
org.apache.struts2.dispatcher.DispatcherConstants.ATTRIBUTES;
  *       </tr>
  *    </tbody>
  * </table>
- *
+ * <p>
  * <!-- END SNIPPET: templateRelatedAttributes -->
- *
+ * <p>
  * <!-- START SNIPPET: generalAttributes -->
  *
  * <table border="1" summary="">
@@ -174,7 +173,7 @@ import static 
org.apache.struts2.dispatcher.DispatcherConstants.ATTRIBUTES;
  *          <td>String</td>
  *          <td>define required label position of form element (left/right), 
default to right</td>
  *       </tr>
-  *       <tr>
+ *       <tr>
  *          <td>errorPosition</td>
  *          <td>xhtml</td>
  *          <td>String</td>
@@ -206,9 +205,9 @@ import static 
org.apache.struts2.dispatcher.DispatcherConstants.ATTRIBUTES;
  *       </tr>
  *    </tbody>
  * </table>
- *
+ * <p>
  * <!-- END SNIPPET: generalAttributes -->
- *
+ * <p>
  * <!-- START SNIPPET: javascriptRelatedAttributes -->
  *
  * <table border="1" summary="">
@@ -301,9 +300,9 @@ import static 
org.apache.struts2.dispatcher.DispatcherConstants.ATTRIBUTES;
  *       </tr>
  *    </tbody>
  * </table>
- *
+ * <p>
  * <!-- END SNIPPET: javascriptRelatedAttributes -->
- *
+ * <p>
  * <!-- START SNIPPET: tooltipattributes -->
  * <strong>Deprecated since 7.0.1</strong
  * <table border="1" summary="">
@@ -343,10 +342,10 @@ import static 
org.apache.struts2.dispatcher.DispatcherConstants.ATTRIBUTES;
  *      <td>The name of the property this input field represents.  This will 
auto populate the name, label, and value</td>
  *   </tr>
  * </table>
- *
+ * <p>
  * <!-- END SNIPPET: tooltipattributes -->
- *
- *
+ * <p>
+ * <p>
  * <!-- START SNIPPET: tooltipdescription -->
  * <p>
  * <strong>tooltipConfig is deprecated, use individual tooltip configuration 
attributes instead </strong>
@@ -379,7 +378,7 @@ import static 
org.apache.struts2.dispatcher.DispatcherConstants.ATTRIBUTES;
  * <b>Example 4:</b> Set tooltip config through the value attribute of the 
param tag<br>
  * <b>Example 5:</b> Set tooltip config through the tooltip attributes of the 
component tag<br>
  * </p>
- *
+ * <p>
  * <!-- END SNIPPET: tooltipdescription -->
  *
  *
@@ -475,21 +474,21 @@ public abstract class UIBean extends Component {
     // shortcut, sets label, name, and value
     protected String key;
 
-    protected String id;
+    private String id;
     protected String cssClass;
     protected String cssStyle;
     protected String cssErrorClass;
     protected String cssErrorStyle;
     protected String disabled;
-    protected String label;
+    private String label;
     protected String labelPosition;
     protected String labelSeparator;
     protected String requiredPosition;
     protected String errorPosition;
-    protected String name;
+    private String name;
     protected String requiredLabel;
     protected String tabindex;
-    protected String value;
+    private String value;
     protected String title;
 
     // HTML scripting events attributes
@@ -569,8 +568,7 @@ public abstract class UIBean extends Component {
             mergeTemplate(writer, buildTemplateName(template, 
getDefaultTemplate()));
         } catch (Exception e) {
             throw new StrutsException(e);
-        }
-        finally {
+        } finally {
             popComponentStack();
         }
 
@@ -684,11 +682,11 @@ public abstract class UIBean extends Component {
 
         if (this.key != null) {
 
-            if(this.name == null) {
+            if (this.name == null) {
                 setName(key);
             }
 
-            if(this.label == null) {
+            if (this.label == null) {
                 // lookup the label from a TextProvider (default value is the 
key)
                 providedLabel = TextProviderHelper.getText(key, key, stack);
             }
@@ -826,10 +824,10 @@ public abstract class UIBean extends Component {
         // create HTML id element
         populateComponentHtmlId(form);
 
-        if (form != null ) {
+        if (form != null) {
             addParameter("form", form.getAttributes());
 
-            if ( translatedName != null ) {
+            if (translatedName != null) {
                 // list should have been created by the form component
                 List<String> tags = (List<String>) 
form.getAttributes().get("tagNames");
                 tags.add(translatedName);
@@ -857,13 +855,12 @@ public abstract class UIBean extends Component {
                 for (Map.Entry<String, String> entry : 
overallTooltipConfigMap.entrySet()) {
                     addParameter(entry.getKey(), entry.getValue());
                 }
-            }
-            else {
+            } else {
                 LOG.warn("No ancestor Form found, javascript based tooltip 
will not work, however standard HTML tooltip using alt and title attribute will 
still work");
             }
 
             //TODO: this is to keep backward compatibility, remove once when 
tooltipConfig is dropped
-            String  jsTooltipEnabled = (String) 
getAttributes().get("jsTooltipEnabled");
+            String jsTooltipEnabled = (String) 
getAttributes().get("jsTooltipEnabled");
             if (jsTooltipEnabled != null)
                 this.javascriptTooltip = jsTooltipEnabled;
 
@@ -907,6 +904,7 @@ public abstract class UIBean extends Component {
 
     /**
      * Tries to calculate the "value" parameter based either on the provided 
{@link #value} or {@link #name}
+     *
      * @param translatedName the already evaluated {@link #name}
      */
     protected void applyValueParameter(String translatedName) {
@@ -1039,7 +1037,7 @@ public abstract class UIBean extends Component {
      * Create HTML id element for the component and populate this component 
parameter
      * map. Additionally, a parameter named escapedId is populated which 
contains the found id value filtered by
      * {@link #escape(String)}, needed eg. for naming Javascript identifiers 
based on the id value.
-     *
+     * <p>
      * The order is as follows :-
      * <ol>
      *   <li>This component id attribute</li>
@@ -1067,30 +1065,58 @@ public abstract class UIBean extends Component {
         //fix for https://issues.apache.org/jira/browse/WW-4299
         //do not assign value to id if tryId is null
         if (tryId != null) {
-          addParameter("id", tryId);
-          addParameter("escapedId", escape(tryId));
+            addParameter("id", tryId);
+            addParameter("escapedId", escape(tryId));
         }
     }
 
     /**
      * Get's the id for referencing element.
+     *
      * @return the id for referencing element.
      */
     public String getId() {
         return id;
     }
 
-    @StrutsTagAttribute(description="HTML id attribute")
+    @StrutsTagAttribute(description = "HTML id attribute")
     public void setId(String id) {
         this.id = id;
     }
 
-    @StrutsTagAttribute(description="The template directory.")
+    /**
+     * Gets the label expression used for rendering an element specific label.
+     *
+     * @return the label expression
+     */
+    public String getLabel() {
+        return label;
+    }
+
+    /**
+     * Gets the name to set for element.
+     *
+     * @return the name
+     */
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * Gets the preset value of input element.
+     *
+     * @return the value
+     */
+    public String getValue() {
+        return value;
+    }
+
+    @StrutsTagAttribute(description = "The template directory.")
     public void setTemplateDir(String templateDir) {
         this.templateDir = templateDir;
     }
 
-    @StrutsTagAttribute(description="The theme (other than default) to use for 
rendering the element")
+    @StrutsTagAttribute(description = "The theme (other than default) to use 
for rendering the element")
     public void setTheme(String theme) {
         this.theme = theme;
     }
@@ -1099,210 +1125,210 @@ public abstract class UIBean extends Component {
         return template;
     }
 
-    @StrutsTagAttribute(description="The template (other than default) to use 
for rendering the element")
+    @StrutsTagAttribute(description = "The template (other than default) to 
use for rendering the element")
     public void setTemplate(String template) {
         this.template = template;
     }
 
-    @StrutsTagAttribute(description="The css class to use for element")
+    @StrutsTagAttribute(description = "The css class to use for element")
     public void setCssClass(String cssClass) {
         this.cssClass = cssClass;
     }
 
-    @StrutsTagAttribute(description="The css style definitions for element to 
use")
+    @StrutsTagAttribute(description = "The css style definitions for element 
to use")
     public void setCssStyle(String cssStyle) {
         this.cssStyle = cssStyle;
     }
 
-    @StrutsTagAttribute(description="The css style definitions for element to 
use - it's an alias of cssStyle attribute.")
+    @StrutsTagAttribute(description = "The css style definitions for element 
to use - it's an alias of cssStyle attribute.")
     public void setStyle(String cssStyle) {
         this.cssStyle = cssStyle;
     }
 
-    @StrutsTagAttribute(description="The css error class to use for element")
+    @StrutsTagAttribute(description = "The css error class to use for element")
     public void setCssErrorClass(String cssErrorClass) {
         this.cssErrorClass = cssErrorClass;
     }
 
-    @StrutsTagAttribute(description="The css error style definitions for 
element to use")
+    @StrutsTagAttribute(description = "The css error style definitions for 
element to use")
     public void setCssErrorStyle(String cssErrorStyle) {
         this.cssErrorStyle = cssErrorStyle;
     }
 
-    @StrutsTagAttribute(description="Set the html title attribute on rendered 
html element")
+    @StrutsTagAttribute(description = "Set the html title attribute on 
rendered html element")
     public void setTitle(String title) {
         this.title = title;
     }
 
-    @StrutsTagAttribute(description="Set the html disabled attribute on 
rendered html element")
+    @StrutsTagAttribute(description = "Set the html disabled attribute on 
rendered html element")
     public void setDisabled(String disabled) {
         this.disabled = disabled;
     }
 
-    @StrutsTagAttribute(description="Label expression used for rendering an 
element specific label")
+    @StrutsTagAttribute(description = "Label expression used for rendering an 
element specific label")
     public void setLabel(String label) {
         this.label = label;
     }
 
-    @StrutsTagAttribute(description="String that will be appended to the 
label", defaultValue=":")
+    @StrutsTagAttribute(description = "String that will be appended to the 
label", defaultValue = ":")
     public void setLabelSeparator(String labelseparator) {
         this.labelSeparator = labelseparator;
     }
 
-    @StrutsTagAttribute(description="Define label position of form element 
(top/left)")
+    @StrutsTagAttribute(description = "Define label position of form element 
(top/left)")
     public void setLabelPosition(String labelPosition) {
         this.labelPosition = labelPosition;
     }
 
-    @StrutsTagAttribute(description="Define required position of required form 
element (left|right)")
+    @StrutsTagAttribute(description = "Define required position of required 
form element (left|right)")
     public void setRequiredPosition(String requiredPosition) {
         this.requiredPosition = requiredPosition;
     }
 
-    @StrutsTagAttribute(description="Define error position of form element 
(top|bottom)")
+    @StrutsTagAttribute(description = "Define error position of form element 
(top|bottom)")
     public void setErrorPosition(String errorPosition) {
         this.errorPosition = errorPosition;
     }
 
-    @StrutsTagAttribute(description="The name to set for element")
+    @StrutsTagAttribute(description = "The name to set for element")
     public void setName(String name) {
         if (name != null && name.startsWith("$")) {
             LOG.error("The name attribute should not usually be a templating 
variable." +
-                      " This can cause a critical vulnerability if the 
resolved value is derived from user input." +
-                      " If you are certain that you require this behaviour, 
please use OGNL expression syntax ( %{expr} ) instead.",
+                            " This can cause a critical vulnerability if the 
resolved value is derived from user input." +
+                            " If you are certain that you require this 
behaviour, please use OGNL expression syntax ( %{expr} ) instead.",
                     new IllegalStateException());
             return;
         }
         this.name = name;
     }
 
-    @StrutsTagAttribute(description="If set to true, the rendered element will 
indicate that input is required", type="Boolean", defaultValue="false")
+    @StrutsTagAttribute(description = "If set to true, the rendered element 
will indicate that input is required", type = "Boolean", defaultValue = "false")
     public void setRequiredLabel(String requiredLabel) {
         this.requiredLabel = requiredLabel;
     }
 
-    @StrutsTagAttribute(description="Set the html tabindex attribute on 
rendered html element")
+    @StrutsTagAttribute(description = "Set the html tabindex attribute on 
rendered html element")
     public void setTabindex(String tabindex) {
         this.tabindex = tabindex;
     }
 
-    @StrutsTagAttribute(description="Preset the value of input element.")
+    @StrutsTagAttribute(description = "Preset the value of input element.")
     public void setValue(String value) {
         this.value = value;
     }
 
-    @StrutsTagAttribute(description="Set the html onclick attribute on 
rendered html element")
+    @StrutsTagAttribute(description = "Set the html onclick attribute on 
rendered html element")
     public void setOnclick(String onclick) {
         this.onclick = onclick;
     }
 
-    @StrutsTagAttribute(description="Set the html ondblclick attribute on 
rendered html element")
+    @StrutsTagAttribute(description = "Set the html ondblclick attribute on 
rendered html element")
     public void setOndblclick(String ondblclick) {
         this.ondblclick = ondblclick;
     }
 
-    @StrutsTagAttribute(description="Set the html onmousedown attribute on 
rendered html element")
+    @StrutsTagAttribute(description = "Set the html onmousedown attribute on 
rendered html element")
     public void setOnmousedown(String onmousedown) {
         this.onmousedown = onmousedown;
     }
 
-    @StrutsTagAttribute(description="Set the html onmouseup attribute on 
rendered html element")
+    @StrutsTagAttribute(description = "Set the html onmouseup attribute on 
rendered html element")
     public void setOnmouseup(String onmouseup) {
         this.onmouseup = onmouseup;
     }
 
-    @StrutsTagAttribute(description="Set the html onmouseover attribute on 
rendered html element")
+    @StrutsTagAttribute(description = "Set the html onmouseover attribute on 
rendered html element")
     public void setOnmouseover(String onmouseover) {
         this.onmouseover = onmouseover;
     }
 
-    @StrutsTagAttribute(description="Set the html onmousemove attribute on 
rendered html element")
+    @StrutsTagAttribute(description = "Set the html onmousemove attribute on 
rendered html element")
     public void setOnmousemove(String onmousemove) {
         this.onmousemove = onmousemove;
     }
 
-    @StrutsTagAttribute(description="Set the html onmouseout attribute on 
rendered html element")
+    @StrutsTagAttribute(description = "Set the html onmouseout attribute on 
rendered html element")
     public void setOnmouseout(String onmouseout) {
         this.onmouseout = onmouseout;
     }
 
-    @StrutsTagAttribute(description="Set the html onfocus attribute on 
rendered html element")
+    @StrutsTagAttribute(description = "Set the html onfocus attribute on 
rendered html element")
     public void setOnfocus(String onfocus) {
         this.onfocus = onfocus;
     }
 
-    @StrutsTagAttribute(description=" Set the html onblur attribute on 
rendered html element")
+    @StrutsTagAttribute(description = " Set the html onblur attribute on 
rendered html element")
     public void setOnblur(String onblur) {
         this.onblur = onblur;
     }
 
-    @StrutsTagAttribute(description="Set the html onkeypress attribute on 
rendered html element")
+    @StrutsTagAttribute(description = "Set the html onkeypress attribute on 
rendered html element")
     public void setOnkeypress(String onkeypress) {
         this.onkeypress = onkeypress;
     }
 
-    @StrutsTagAttribute(description="Set the html onkeydown attribute on 
rendered html element")
+    @StrutsTagAttribute(description = "Set the html onkeydown attribute on 
rendered html element")
     public void setOnkeydown(String onkeydown) {
         this.onkeydown = onkeydown;
     }
 
-    @StrutsTagAttribute(description="Set the html onkeyup attribute on 
rendered html element")
+    @StrutsTagAttribute(description = "Set the html onkeyup attribute on 
rendered html element")
     public void setOnkeyup(String onkeyup) {
         this.onkeyup = onkeyup;
     }
 
-    @StrutsTagAttribute(description="Set the html onselect attribute on 
rendered html element")
+    @StrutsTagAttribute(description = "Set the html onselect attribute on 
rendered html element")
     public void setOnselect(String onselect) {
         this.onselect = onselect;
     }
 
-    @StrutsTagAttribute(description="Set the html onchange attribute on 
rendered html element")
+    @StrutsTagAttribute(description = "Set the html onchange attribute on 
rendered html element")
     public void setOnchange(String onchange) {
         this.onchange = onchange;
     }
 
-    @StrutsTagAttribute(description="Set the html accesskey attribute on 
rendered html element")
+    @StrutsTagAttribute(description = "Set the html accesskey attribute on 
rendered html element")
     public void setAccesskey(String accesskey) {
         this.accesskey = accesskey;
     }
 
-    @StrutsTagAttribute(description="Set the tooltip of this particular 
component")
+    @StrutsTagAttribute(description = "Set the tooltip of this particular 
component")
     @Deprecated(since = "7.0.1", forRemoval = true)
     public void setTooltip(String tooltip) {
         this.tooltip = tooltip;
     }
 
-    @StrutsTagAttribute(description="Deprecated. Use individual tooltip 
configuration attributes instead.")
+    @StrutsTagAttribute(description = "Deprecated. Use individual tooltip 
configuration attributes instead.")
     @Deprecated(since = "7.0.1", forRemoval = true)
     public void setTooltipConfig(String tooltipConfig) {
         this.tooltipConfig = tooltipConfig;
     }
 
-    @StrutsTagAttribute(description="Set the key (name, value, label) for this 
particular component")
+    @StrutsTagAttribute(description = "Set the key (name, value, label) for 
this particular component")
     public void setKey(String key) {
         this.key = key;
     }
 
-    @StrutsTagAttribute(description="Use JavaScript to generate tooltips", 
type="Boolean", defaultValue="false")
+    @StrutsTagAttribute(description = "Use JavaScript to generate tooltips", 
type = "Boolean", defaultValue = "false")
     @Deprecated(since = "7.0.1", forRemoval = true)
     public void setJavascriptTooltip(String javascriptTooltip) {
         this.javascriptTooltip = javascriptTooltip;
     }
 
-    @StrutsTagAttribute(description="CSS class applied to JavaScrip tooltips", 
defaultValue="StrutsTTClassic")
+    @StrutsTagAttribute(description = "CSS class applied to JavaScrip 
tooltips", defaultValue = "StrutsTTClassic")
     @Deprecated(since = "7.0.1", forRemoval = true)
     public void setTooltipCssClass(String tooltipCssClass) {
         this.tooltipCssClass = tooltipCssClass;
     }
 
-    @StrutsTagAttribute(description="Delay in milliseconds, before showing 
JavaScript tooltips ",
-        defaultValue="Classic")
+    @StrutsTagAttribute(description = "Delay in milliseconds, before showing 
JavaScript tooltips ",
+            defaultValue = "Classic")
     @Deprecated(since = "7.0.1", forRemoval = true)
     public void setTooltipDelay(String tooltipDelay) {
         this.tooltipDelay = tooltipDelay;
     }
 
-    @StrutsTagAttribute(description="Icon path used for image that will have 
the tooltip")
+    @StrutsTagAttribute(description = "Icon path used for image that will have 
the tooltip")
     @Deprecated(since = "7.0.1", forRemoval = true)
     public void setTooltipIconPath(String tooltipIconPath) {
         this.tooltipIconPath = tooltipIconPath;
@@ -1326,13 +1352,14 @@ public abstract class UIBean extends Component {
 
     /**
      * supports dynamic attributes for freemarker ui tags
+     *
      * @see <a href="https://issues.apache.org/jira/browse/WW-3174";>WW-3174</a>
      * @see <a href="https://issues.apache.org/jira/browse/WW-4166";>WW-4166</a>
      */
     @Override
     public void copyAttributes(Map<String, Object> attributesToCopy) {
         super.copyAttributes(attributesToCopy);
-        for (Map.Entry<String, Object>entry : attributesToCopy.entrySet()) {
+        for (Map.Entry<String, Object> entry : attributesToCopy.entrySet()) {
             String entryKey = entry.getKey();
             if (!isValidTagAttribute(entryKey) && 
!entryKey.equals("dynamicAttributes")) {
                 dynamicAttributes.put(entryKey, entry.getValue());
diff --git a/core/src/test/java/org/apache/struts2/components/UIBeanTest.java 
b/core/src/test/java/org/apache/struts2/components/UIBeanTest.java
index cc194bd08..811040478 100644
--- a/core/src/test/java/org/apache/struts2/components/UIBeanTest.java
+++ b/core/src/test/java/org/apache/struts2/components/UIBeanTest.java
@@ -19,15 +19,15 @@
 package org.apache.struts2.components;
 
 import org.apache.struts2.ActionContext;
-import org.apache.struts2.config.ConfigurationException;
-import org.apache.struts2.util.ValueStack;
 import org.apache.struts2.StrutsConstants;
 import org.apache.struts2.StrutsInternalTestCase;
 import org.apache.struts2.components.template.Template;
 import org.apache.struts2.components.template.TemplateEngine;
 import org.apache.struts2.components.template.TemplateEngineManager;
+import org.apache.struts2.config.ConfigurationException;
 import org.apache.struts2.dispatcher.SessionMap;
 import org.apache.struts2.dispatcher.StaticContentLoader;
+import org.apache.struts2.util.ValueStack;
 import org.springframework.mock.web.MockHttpServletRequest;
 import org.springframework.mock.web.MockHttpServletResponse;
 import org.springframework.mock.web.MockHttpSession;
@@ -412,7 +412,7 @@ public class UIBeanTest extends StrutsInternalTestCase {
     }
 
     public void testNonceOfRequestAttribute() {
-        Map<String, String> params = new HashMap<String, String>(){{
+        Map<String, String> params = new HashMap<String, String>() {{
             put(StrutsConstants.STRUTS_CSP_NONCE_SOURCE, "request");
         }};
         initDispatcher(params);
@@ -487,7 +487,61 @@ public class UIBeanTest extends StrutsInternalTestCase {
     public void testPotentialDoubleEvaluationWarning() {
         bean.setName("${someVar}");
 
-        assertNull(bean.name);
+        assertNull(bean.getName());
+    }
+
+    /**
+     * Test that UIBean fields (label, name, value, id) being private doesn't 
cause
+     * OGNL security warnings when evaluating getText() expressions.
+     * <p>
+     * This is a regression test for WW-5368 where using getText() with 
resource bundle
+     * keys starting with "label" would trigger OGNL SecurityMemberAccess 
warnings:
+     * "Access to non-public [protected java.lang.String 
org.apache.struts2.components.UIBean.label] is blocked!"
+     * <p>
+     * By changing these fields from protected to private with public getters, 
OGNL's
+     * introspection will find the public getter methods instead of attempting 
to access
+     * the fields directly, eliminating the false-positive security warnings.
+     */
+    public void testNoOgnlWarningsForProtectedFields() {
+        ValueStack stack = ActionContext.getContext().getValueStack();
+        MockHttpServletRequest req = new MockHttpServletRequest();
+        MockHttpServletResponse res = new MockHttpServletResponse();
+        ActionContext.getContext().withServletRequest(req);
+
+        // Create a UIBean component to push onto the stack
+        TextField txtFld = new TextField(stack, req, res);
+        txtFld.setLabel("Test Label");
+        txtFld.setName("testName");
+        txtFld.setValue("testValue");
+        txtFld.setId("testId");
+
+        container.inject(txtFld);
+
+        // Push the component onto the stack to simulate tag rendering context
+        stack.push(txtFld);
+
+        try {
+            // These expressions simulate getText() calls with resource bundle 
keys
+            // that start with field names. OGNL should use public getters, 
not field access
+            Object labelResult = stack.findValue("label");
+            Object nameResult = stack.findValue("name");
+            Object valueResult = stack.findValue("value");
+            Object idResult = stack.findValue("id");
+
+            // Verify the values are accessible via getters
+            assertEquals("Test Label", labelResult);
+            assertEquals("testName", nameResult);
+            assertEquals("testValue", valueResult);
+            assertEquals("testId", idResult);
+
+            // Verify the public getters are accessible
+            assertNotNull(txtFld.getLabel());
+            assertNotNull(txtFld.getName());
+            assertNotNull(txtFld.getValue());
+            assertNotNull(txtFld.getId());
+        } finally {
+            stack.pop();
+        }
     }
 
 }

Reply via email to