Hello, I have a Struts 6.4 page with a select, and I have a problem populating the list attribute.
<s:select id="searchView_showSecured" data-mdb-select-init="" name="searchView.showSecured" theme="simple" list="yesNoAllList" listKey="id" listValue="label" /> What I'm trying to do is relatively simple: I have the following action code: public class MachineParameterOverviewBootstrapAction extends OverviewActionSupport implements Expirable { ... } And this is the super action. Notably, this getter does NOT have an underlying field property. public class OverviewActionSupport extends BaseActionSupport { ... public List<SelectOptionView> getYesNoAllList() { return BootstrapSupport.getInstance().getYesNoAllList(); } } In the Tomcat log, I get this error: Caused by: tag 'select', field 'list', name 'searchView.showSecured': The requested list key 'yesNoAllList' could not be resolved as a collection/array/map/enumeration/iterator type. Example: people or people.{name} - [unknown location] at org.apache.struts2.components.Component.fieldError(Component.java:284) at org.apache.struts2.components.Component.findValue(Component.java:363) at org.apache.struts2.components.ListUIBean.evaluateExtraParams(ListUIBean.java:78) at org.apache.struts2.components.Select.evaluateExtraParams(Select.java:101) at org.apache.struts2.components.UIBean.evaluateParams(UIBean.java:884) at org.apache.struts2.components.UIBean.end(UIBean.java:550) at org.apache.struts2.views.jsp.ComponentTagSupport.doEndTag(ComponentTagSupport.java:40) at org.apache.jsp.jsp.machineparameter.machineParameterOverviewBootstrap_jsp._jspx_meth_s_005fselect_005f1(machineParameterOverviewBootstrap_jsp.java:11949) at org.apache.jsp.jsp.machineparameter.machineParameterOverviewBootstrap_jsp._jspService(machineParameterOverviewBootstrap_jsp.java:1209) at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70) at javax.servlet.http.HttpServlet.service(HttpServlet.java:623) at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:466) ... 118 more I assumed that Struts 6.4 would use getters and setters to interact with properties on the page, because AFAIK that's what it did in Struts 2.3 and 2.5, and hence I could just use a getter without having a field property with the corresponding name on the action. Is that assumption incorrect? For completeness, this is BootstrapSupport.java: public final class BootstrapSupport extends ActionSupport { /** * */ private static final long serialVersionUID = 3159663106530217293L; private BootstrapSupport() { loadYesNoAllOptionsMap(); } private static final BootstrapSupport INSTANCE = new BootstrapSupport(); /** * The text provider, initialized with an instance of the CustomTextProvider. */ private final transient TextProvider textProvider = new CustomMessageResourcesFactory().createInstance(getClass(), this); private List<SelectOptionView> yesNoAllList; private List<SelectOptionView> yesNoList; public static BootstrapSupport getInstance() { return INSTANCE; } /** * This is used to help generate the yesnoall options dojo string */ private static final int YNA_NO = CommonUtils.DO_NOT_SHOW_ENTRIES; private static final int YNA_YES = CommonUtils.SHOW_ENTRIES; private static final int YNA_ALL = CommonUtils.SHOW_ALL_ENTRIES; // Operating System description private static final String[][] YESNOALLDESCRIPTIONS = { { YNA_YES + "", MasterCodeDescriptionKeys.MC_YESNOALL_YES }, { YNA_NO + "", MasterCodeDescriptionKeys.MC_YESNOALL_NO }, { YNA_ALL + "", MasterCodeDescriptionKeys.MC_YESNOALL_ALL } }; // Operating System description private static final String[][] YESNODESCRIPTIONS = { { YNA_YES + "", MasterCodeDescriptionKeys.MC_YESNOALL_YES }, { YNA_NO + "", MasterCodeDescriptionKeys.MC_YESNOALL_NO } }; /** * This method is automatically called by Struts, it injects the value of the * StrutsConstants.STRUTS_CUSTOM_I18N_RESOURCES. The values is set as the static * field of the CustomLocalizedTextUtil class, which is needed when loading * messages from the resource bundles. * * @param strutsCustomI18nResources The property value */ @Inject(StrutsConstants.STRUTS_CUSTOM_I18N_RESOURCES) public void setStrutsCustomI18nResources(String strutsCustomI18nResources) { if (CustomLocalizedTextUtil.getStrutsCustomI18nResources() == null) { CustomLocalizedTextUtil.setStrutsCustomI18nResources(strutsCustomI18nResources); CustomLocalizedTextUtil.clearDefaultResourceBundles(); } } /** * @see com.opensymphony.xwork2.ActionSupport#getText(String) */ public String getText(String aTextName) { return textProvider.getText(aTextName); } /** * This generates the Bootstrap String for the YesNoAll Options. */ private void createAutocompleteViewListForYesNoAllOptionsMap() { yesNoAllList = new ArrayList<SelectOptionView>(); for (String[] yesNoAllOption : YESNOALLDESCRIPTIONS) { SelectOptionView selectOptionView = new SelectOptionView(); selectOptionView.setLabel(getText(yesNoAllOption[1])); selectOptionView.setId(yesNoAllOption[0]); yesNoAllList.add(selectOptionView); } } /** * This generates the Bootstrap String for the YesNoAll Options. */ private void createAutocompleteViewListForYesNoOptionsMap() { yesNoList = new ArrayList<SelectOptionView>(); for (String[] yesNoOption : YESNODESCRIPTIONS) { SelectOptionView selectOptionView = new SelectOptionView(); selectOptionView.setLabel(getText(yesNoOption[1])); selectOptionView.setId(yesNoOption[0]); yesNoList.add(selectOptionView); } } /** * Load the Yes/No/All optionset map */ public void loadYesNoAllOptionsMap() { createAutocompleteViewListForYesNoAllOptionsMap(); createAutocompleteViewListForYesNoOptionsMap(); } public List<SelectOptionView> getYesNoAllList() { return yesNoAllList; } public List<SelectOptionView> getYesNoList() { return yesNoList; } } Kind regards, Nate Kerkhofs