Thursday, October 21, 2010

Multiple faces-config.xml files in a J2EE Web Application



Many times we wonder on how large the application has become and how much pain it is to maintain the application. One of the strategies to answer such problem could be splitting faces-config.xml into multiple parts so that organising become much easier.
Following strategies could be followed to split faces-config.xml
1.       Writing a custom configurer (for jsf1.1 only): to load multiple faces-config files a cutom ConfigureListener could be written. Following code snippet does the job
import com.sun.faces.config.ConfigureListener;
import com.sun.faces.config.ConfigureListener;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextListener;

public class MyConfigureListener extends ConfigureListener implements ServletContextListener {
    /**
     * <p>
     * Configure the JavaServer Faces reference implementation based on the
     * accumulated configuration beans.
     * </p>
     *
     * @param context
     *            <code>ServletContext</code> for this web application
     * @param config
     *            <code>FacesConfigBean</code> that is the root of the tree of
     *            configuration information
     */
    protected void configure(ServletContext context, FacesConfigBean config) throws Exception {
/**
     * Write code to load faces-config
     */
}
}
Following would go inside web.xml to load this custom configure listener.
<listener>
      <listener-class>com.ameya.MyConfigureListener</listener-class>
</listener>



2.       Using CONFIG_FILES init param: Sun’s in-built ConfigureListener could be used for loading multiple faces-config.xml files. No Java code needs to be written.
Following would go inside web.xml.

<context-param>
      <param-name>javax.faces.CONFIG_FILES</param-name>
      <param-value>/WEB-INF/faces-config.xml,
            /WEB-INF/component1/faces-config.xml,
            /classpath:faces-config2.xml,
            /WebApp/Jsps/some-config.xml</param-value>
</context-param>


<listener>
      <listener-class>com.sun.faces.config.ConfigureListener</listener-class>
</listener>

Please note the following for using Sun’s Configure Listener.
1.       The path should always start with a forward slash ‘/’.
2.       The JSF libraries can load faces-config.xml from anywhere within the classpath of the application but it is always recommended to have resources like faces-config inside WEB-INF folder to make the web application more secure. The WebContainer would not entertain any client request for a resource inside WEB-INF folder.
3.       If there is any error while loading a faces-config.xml, the entire process stops and no other faces-config.xml would be loaded either.
4.       The JSF libraries also maintain the order of faces-config.xml files. The files loaded the last would have precedence over the ones loaded before it. This feature comes handy when the web application is developed in a component based structure and it is required to override managed-beans or navigation-cases.

Following is the internal behavior of JSF libraries when they attempt to load multiple faces-config.xml files from a J2EE web application
  1. Load each faces-config.xml file from “META-INF” folder from each JAR inside the “WEB-INF/lib” folder of the web application
  2. Look for context level init parameter named “javax.faces.CONFIG_FILES” inside web.xml. JSF expects it to be a comma separated list of faces configuration files. The last entry takes precedence over others.
  3. Load faces-config.xml file from WEB-INF directory.

Any comments / suggestions on the topic are welcome.


No comments:

Post a Comment