3 Replies Latest reply on Aug 14, 2012 1:08 PM by cfang

    Setting JSF ProjectStage with JNDI

    rcd

      By default, JSF ProjectStage can only be configured two ways in Mojarra: either through a context-param in web.xml or through the java:comp/env/jsf/ProjectStage JNDI binding. I don't want this setting in web.xml because that makes it much more difficult to change, and places a deployment-time flag in a build-time configuration file. So I tried to put the appropriate JNDI binding in standalone.xml instead, but JBoss will not allow binding to that name, even in 7.2.0.Alpha1 snapshots, where it fails with this message:

       

      {code}

      10:50:34,057 ERROR [org.jboss.as.controller.management-operation] (ServerService Thread Pool -- 54) JBAS014613: Operation ("add") failed - address: ([

          ("subsystem" => "naming"),

          ("binding" => "java:comp/env/jsf/ProjectStage")

      ]) - failure description: "JBAS011864: Invaliding binding name java:comp/env/jsf/ProjectStage, name must start with one of [java:global, java:jboss, java:/]"

      {code}

       

      Is this a bug or is this deliberately being prevented for some reason?

       

      On a related note, MyFaces goes beyond the JSF spec and allows configuring the ProjectStage with a system property. Mojarra has an open issue for such a feature, but it is, understandably, a low priority. Mojarra, in general, feels buggy to me, so I attempted to replace it with MyFaces. MyFaces seems to work for some people in 7.2.0.Alpha1 snapshots, but it fails for me because of classloader issues related to Weld (see AS7-1628).

       

      In the past, I've replicated the MyFaces feature on Mojarra by creating an ApplicationFactory wrapper that returns the ProjectStage from a system property. This works, but it's annoying to use in conjunction with Seam Faces and MyFaces CODI. Those CDI extensions make the ProjectStage available for injection, which may be used before the JSF application is instantiated, so the wrapper doesn't affect them. (CODI even goes as far as to clone the ProjectStage feature and make it available for general use without JSF.) Both allow configuring the ProjectStage through a system property, but the name is inconsistent. So I either have to implement at least one of their SPIs, to get the value from a different system property, or I have to pass the same value for both properties. Again, not really a problem, just annoying. But if I could get the JNDI binding to work, that would completely solve the problem as Mojarra, Seam, and CODI all look at that by default.

        • 1. Re: Setting JSF ProjectStage with JNDI
          cfang

          java:comp/env/jsf/ProjectStage, as the name suggests, is scoped to your web app component.  So standalone.xml is the wrong place for it.

           

          You will need to declare a <env-entry> whose name is jsf/ProjectStage, to make java:comp/env/jsf/ProjectStage available to your app.

          • 2. Re: Setting JSF ProjectStage with JNDI
            ssilvert

            You want to set this value outside of your WAR.  So standalone.xml is indeed the correct place for it.

             

            In CLI or CLI GUI, do this:

            /subsystem=naming/binding=java\:\/env\/jsf\/ProjectStage/:add(binding-type=simple,value=Development,class=java.lang.String)
            

             

            For CLI GUI, you can scroll down to /subsystem=naming/binding=*, right-click, and choose "add" from the menu.  The nice thing about CLI GUI in this case is that it will automatically put in your escape characters.  But if you just cut and paste the above, it will work in plain CLI.

             

            Then in web.xml, do this:

            <resource-ref>
                    <res-ref-name>jsf/ProjectStage</res-ref-name>
                    <res-type>java.lang.String</res-type>
             </resource-ref>
            

             

            And in jboss-web.xml, do this:

            <?xml version="1.0" encoding="ISO-8859-1"?>
            <jboss-web>
                <resource-ref>
                    <res-ref-name>jsf/ProjectStage</res-ref-name>
                    <res-type>java.lang.String</res-type>
                    <jndi-name>java:/env/jsf/ProjectStage</jndi-name>
                </resource-ref>
            </jboss-web>
            

             

            Then to change the global value for ProjectStage, just do a write-attribute operation:

            /subsystem=naming/binding=java\:\/env\/jsf\/ProjectStage/:write-attribute(name=value,value=Production)
            

             

            Stan

            • 3. Re: Setting JSF ProjectStage with JNDI
              cfang

              Thanks Stan for the detailed instructions.  I wasn't sure how the mapping is done so I suggested keeping everything in standard descriptor.