
Project stages
Having a <h:messages> tag on every JSF page is a good idea; without it, the user might not see validation messages and will have no idea why the form submission is not going through. By default, JSF validation messages do not generate any output in the application server log. A common mistake new JSF developers make is failing to add a <h:messages> tag to their pages; without it, if validation fails, then the navigation seems to fail for no reason (the same page is rendered if navigation fails and, without a <h:messages> tag, no error messages are displayed in the browser).
To avoid this situation, JSF 2.0 introduced the concept of project stages.
The following project stages are defined in JSF 2.0 and newer versions:
- Production
- Development
- UnitTest
- SystemTest
We can define the project stage as an initialization parameter to the Faces servlet in web.xml, or as a custom JNDI resource. The preferred way of setting the project stage is through a custom JNDI resource.
The process to map global JNDI resources to component resources is application server-specific; when using GlassFish, a change needs to be made to the application's web.xml, plus we need to use a GlassFish-specific deployment descriptor.
Setting up a custom JNDI resource is application server-specific, consult your application server documentation for details. If we are using GlassFish to deploy our application, we can set up a custom JNDI by logging in to the web console, navigating to JNDI | Custom Resources, then clicking the New... button:
In the resulting page, we need to enter the following information:

After entering these two values, the Factory Class field will be automatically populated with the value : org.glassfish.resources.custom.factory.PrimitivesAndStringFactory.
After entering the values, we need to add a new property with a name of value and a value corresponding to the project stage we want to use (Development, in the preceding screenshot).
Setting the project stage allows us to perform some logic only if we are running in a specific stage. For instance, in one of our named beans, we could have code that looks like this:
Application application = facesContext.getApplication(); if (application.getProjectStage().equals( ProjectStage.Production)) { //do production stuff } else if (application.getProjectStage().equals( ProjectStage.Development)) { //do development stuff } else if (application.getProjectStage().equals( ProjectStage.UnitTest)) { //do unit test stuff } else if (application.getProjectStage().equals( ProjectStage.SystemTest)) { //do system test stuff }
As we can see, project stages allow us to modify our code's behavior for different environments. More importantly, setting the project stage allows the JSF engine to behave a bit differently based on the project stage setting. Relevant to our discussion, setting the project stage to Development results in additional logging statements in the application server log. Therefore, if we forget to add a <h:messages> tag to our page, our project stage is Development, and validation fails; a Validation Error will be displayed on the page even if we omit the <h:messages> component:
In the default Production stage, this error message is not displayed in the page, leaving us confused as to why our page navigation doesn't seem to be working.