Hi there,

I think that there is a bug in the implementation of the "
org.apache.struts.faces.taglib.LoadMessagesTag". When working in a
multimodule webapp with several <messages-resources /> per module, the
<s:loadMessages /> tag can't find the appropiate MessageResources instance
via "messages" attribute.

The reason for this is the way that the tag uses to locate the appropiate
MessageResources instance. This code explains it (line 76):

public int doStartTag() {

       // Acquire the Locale to be wrapped
       Locale locale =
           FacesContext.getCurrentInstance().getViewRoot().getLocale();

       // Acquire the MessageResources to be wrapped
       MessageResources messages = null;
       if (this.messages == null) {
           messages = (MessageResources)
               pageContext.getAttribute(Globals.MESSAGES_KEY,
                                        PageContext.REQUEST_SCOPE);
           if (messages == null) {
               messages = (MessageResources)
                   pageContext.getAttribute(Globals.MESSAGES_KEY,
                                            PageContext.APPLICATION_SCOPE);
           }
       } else {
           messages = (MessageResources)
               pageContext.getAttribute(this.messages,
                                        PageContext.REQUEST_SCOPE);
       }

       // Expose a Map instance under the specified request attribute key
       pageContext.setAttribute(var,
                                new MessagesMap(messages, locale),
                                PageContext.APPLICATION_SCOPE);

       // Skip the body of this tag (if any)
       return (SKIP_BODY);

   }

As you can see, this code doesn't supports modules.

If we want to load a different bundle than the one configured as the
default, we must use the "messages" attribute but this code tries to load
that MessageResources instance from the APPLICATION_SCOPE rather that search
for it inside the REQUEST_SCOPE.

In a multimodule webapp the MessageResources instances are loaded on startup
inside the APPLICATION_SCOPE with the key:
org.apache.struts.action/MESSAGE + [modulePrefix]

If we have more than one MessageResources instance per module the will be
loaded with the key:
[bundleKey] + [modulePrefix]


So, the above code can't load any of those kind of messages resources. This
can be solved easily:

public int doStartTag() throws JspException {

       // Acquire the Locale to be wrapped
       Locale locale =
           FacesContext.getCurrentInstance().getViewRoot().getLocale();

       ModuleConfig modConfig = ModuleUtils.getInstance().getModuleConfig(
           (HttpServletRequest) pageContext.getRequest(),
pageContext.getServletContext());

       // Acquire the MessageResources to be wrapped
       MessageResources messages = null;
       if (this.messages == null) {
           messages = (MessageResources)
               pageContext.getAttribute(Globals.MESSAGES_KEY,
                                        PageContext.REQUEST_SCOPE);
           if (messages == null) {
               messages = (MessageResources)
                   pageContext.getAttribute(Globals.MESSAGES_KEY +
modConfig.getPrefix(),
                                            PageContext.APPLICATION_SCOPE);
           }
       } else {
           messages = (MessageResources)
               pageContext.getAttribute(this.messages,
                                        PageContext.REQUEST_SCOPE);

           if(messages == null) {
               messages = (MessageResources)
                   pageContext.getAttribute(this.messages +
modConfig.getPrefix(),
                                           PageContext.APPLICATION_SCOPE);
           }
       }

       if(messages == null)
           throw new JspException("MessageResources bundle " +
                                              this.messages + " not
found");

       // Expose a Map instance under the specified request attribute key
       pageContext.setAttribute(var,
                                new MessagesMap(messages, locale),
                                PageContext.REQUEST_SCOPE);

       // Skip the body of this tag (if any)
       return (SKIP_BODY);

   }

Should I open a new issue about this?

Alonso

Reply via email to