Facelets compositions (so, just plain *.xhtml
pages, templates and include files) are resolved by ExternalContext#getResource()
which delegates to ServletContext#getResource()
. This requires a Servlet 3.x compatible container because /WEB-INF/lib/*.jar!/META-INF/resources
resolving from is new since Servlet 3.0. If you aren't on Servlet 3.x yet, or want to put those JARs on a different location for some reason, then you'd need to create a custom ResourceResolver
. See also How to create a modular JSF 2.0 application?
Facelets composite components and static resources (so, <cc:xxx>
components and CSS/JS/image resources which are to be loaded by <h:outputStylesheet>
, <h:outputScript>
and <h:graphicImage>
) are resolved from the classpath by ClassLoader#getResource()
. To include the JAR file in the classpath scan of JSF, you'd need to include a JSF 2.x compatible faces-config.xml
file in the /META-INF
folder of the JAR file. The same story applies to @ManagedBean
, @FacesValidator
, @FacesConverter
, @FacesComponent
and other JSF artifacts.
When developing in Eclipse, you can choose Web > Web Fragment Project to create such a module project. It is not much different from a normal Java project, expect that it will implicitly include JavaScript facet and a targeted runtime, autocreate a /META-INF/web-fragment.xml
file and get associated with an existing Dynamic Web Project by adding itself as a deployment assembly to that project.
You can also use an existing standard Java project with the right folder structure prepared. The /META-INF
folder has to go in Java source folder. The web-fragment.xml
file is by the way optional. You just have to manually add the Java project to the Deployment Assembly section of the main web project properties. Do not add it as another project in project's Build Path section.
When you're (manually) building a JAR file out of it, you need to make sure that the directory entries are added to the JAR, otherwise Facelets compositions can't be resolved. If you're building by build tools like Eclipse/Ant/Maven/etc, this has also to be taken into account. If this is not controllable, a custom ResourceResolver
is the most reliable approach.