Unable to find or serve localized resource from jsf-resource-library

3.3k views Asked by At

I am trying to replicate an example from a book,

The structure can be visualized from the image attached below-

UPDATED

enter image description here

The view for which the library will be used is as simple as this given below-

<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://xmlns.jcp.org/jsf/html"
      xmlns:f="http://xmlns.jcp.org/jsf/core">
    <h:head>
        <title></title>
        <h:outputStylesheet library="#{facesContext.viewRoot.locale}/default" name="css/rafa.css"/>
        <h:outputScript library="#{facesContext.viewRoot.locale}/default" name="rafa.js"/>        
    </h:head>
    <h:body>   
        <f:view locale="#{localeBean.mylocale}">     
            <div style="width:100%; text-align:center">
                <h:form>
                    <h:commandButton value="Rafa at Roland Garros" action="#{localeBean.changeLocale('fr')}"/>
                    <h:commandButton value="Rafa at Wimbledon" action="#{localeBean.changeLocale('en')}"/>
                    <h:commandButton value="Rafa at US Open" action="#{localeBean.changeLocale('us')}"/>
                    <h:commandButton value="Rafa at Australian Open" action="#{localeBean.changeLocale('au')}"/>
                </h:form>
            </div>
            <div style="width:100%; text-align:center">
                <!--<h:graphicImage library="#{facesContext.viewRoot.locale}/default" name="img/rafa.png"/> -->
                <h:graphicImage value="#{resource[facesContext.viewRoot.locale+='/default:img/rafa.png']}"/>
            </div>
        </f:view>
    </h:body>
</html>

with a

@Named
@RequestScoped
public class LocaleBean {

    private String mylocale = "fr";
    // getters & setters
}

I am using Glassfish 4.1.1 Application Server with Mojarra 2.2.12 being used internally,

The rendered HTML is-

<html xmlns="http://www.w3.org/1999/xhtml">
    <head id="j_idt2">
        <title></title>
        <script type="text/javascript" src="/glassfish-ee/javax.faces.resource/rafa.js.xhtml?ln=fr/default&amp;v=1_01_2">
        </script><link type="text/css" rel="stylesheet" href="/glassfish-ee/javax.faces.resource/css/rafa.css.xhtml?ln=fr/default&amp;v=1_0" />
    </head>
    <body>     
        <div style="width:100%; text-align:center">
        <form id="j_idt8" name="j_idt8" method="post" action="/glassfish-ee/ch5/ch5_12/index.xhtml" enctype="application/x-www-form-urlencoded">
            <input type="hidden" name="j_idt8" value="j_idt8" />
            <input type="submit" name="j_idt8:j_idt9" value="Rafa at Roland Garros" />
            <input type="submit" name="j_idt8:j_idt10" value="Rafa at Wimbledon" />
            <input type="submit" name="j_idt8:j_idt11" value="Rafa at US Open" />
            <input type="submit" name="j_idt8:j_idt12" value="Rafa at Australian Open" />
            <input type="hidden" name="javax.faces.ViewState" id="j_id1:javax.faces.ViewState:0" value="---somevalue---" autocomplete="off" />
        </form>
        </div>
            <div style="width:100%; text-align:center">
                <!--&lt;h:graphicImage library="fr/default" name="img/rafa.png"/&gt; -->
                <img src="/glassfish-ee/javax.faces.resource/img/rafa.png.xhtml?ln=fr/default&amp;v=1_0" />
            </div>
    </body>
</html>

The relative urls of interest in rendered html-

http://localhost:8080/glassfish-ee/javax.faces.resource/rafa.js.xhtml?ln=fr/default&v=1_01_2
http://localhost:8080/glassfish-ee/javax.faces.resource/css/rafa.css.xhtml?ln=fr/default&v=1_0
http://localhost:8080/glassfish-ee/javax.faces.resource/img/rafa.png.xhtml?ln=fr/default&v=1_0

On the console, I get this-

2016-06-08T20:54:52.672+0530|WARNING: JSF1064: Unable to find or serve resource, rafa.js, from library, fr/default.
2016-06-08T20:54:52.673+0530|WARNING: JSF1064: Unable to find or serve resource, css/rafa.css, from library, fr/default.
2016-06-08T20:54:52.717+0530|WARNING: JSF1064: Unable to find or serve resource, img/rafa.png, from library, fr/default.
2016-06-08T20:54:57.570+0530|WARNING: JSF1064: Unable to find or serve resource, css/rafa.css, from library, fr/default.
2016-06-08T20:56:05.587+0530|WARNING: JSF1064: Unable to find or serve resource, img/rafa.png, from library, fr/default.
2016-06-08T20:56:09.542+0530|WARNING: JSF1064: Unable to find or serve resource, img/rafa.png, from library, fr/default.

console tab of Google chrome shows-

enter image description here

So finally, where am I going wrong?
Please suggest.


After taking the help of the answer suggested below, with changes,

enter image description here

with an entry-

javax.faces.resource.localePrefix=fr

Accessing the page with a GET request, an alert pops up due to the following entry in 1_2.js file depicted as selected in the structure attached above.

alert("J'ai gagné Roland Garros ...(resources/fr/1_0/css/js/rafa.js/1_2.js)");

enter image description here

I see the same alert popping-up even when after I have changed the locale by pressing the desired command button.

Why? What further needs to be done? Thanks in advance.

1

There are 1 answers

2
BalusC On BEST ANSWER

The resource localization feature is pretty poorly documented in the JSF specification. On the contrary to what you'd intuitively expect, the localized subfolders won't be matched against <f:view locale>. Instead, they will be matched against the <message-bundle> entry identified with the key ResourceHandler.LOCALE_PREFIX which has a value of javax.faces.resource.localePrefix. Also, you shouldn't have the need to explicitly include #{view.locale} in the library attribute.

In order to get it to work, make sure you've declared a <message-bundle> in faces-config.xml.

<application>
    <message-bundle>com.example.i18n.YourBundle</message-bundle>
</application>

And make sure that it has at least the below entry:

javax.faces.resource.localePrefix=fr

Then you can just reference the resources the usual way, without any mess with locale prefix and version suffix.

<h:outputStylesheet library="default" name="css/rafa.css" />
<h:outputScript library="default" name="rafa.js" />

I admit that this can be done better. When the <message-bundle> is not specified and/or the javax.faces.resource.localePrefix is absent, then it should simply fall back to the UIViewRoot#getLocale(). Nonetheless, this is certainly one of the rarest used JSF features. I frankly never tried it until today and I don't think I would ever use it in a real world application.