As always, i’m a little confused.
Here https://community.jboss.org/wiki/ModularWebAppsWithJSF2 i’ve learned that it is easy and works out of the box to bundle templates in separate jars since JSF 2.0.
The only problem is: i can’t get it working. I simply deploy a “page.xhtml” in all flavors (META-INF directory, resources directory, root; with and without faces-config.xml) in a jar that is included in the web application WEB-INF/lib and request something like http://host/demo/faces/page.xhtml or do an “include” or “decorate” on the template. I get an exception.
Here Java EE6> Packaging JSF facelets (xhtml) and ManagedBeans as JAR my favorite JSF teacher explains to use a custom ResourceResolver to do exactly this. As i debugged the resource resolving i have no doubt that this will work and will give it a try.
This is the question about the mechanics – what is the difference between the two approaches?
Which resources exactly are looked up in META-INF/resources automatically?
Facelets compositions (so, just plain
*.xhtmlpages, templates and include files) are resolved byExternalContext#getResource()which delegates toServletContext#getResource(). This requires a Servlet 3.x compatible container because/WEB-INF/lib/*.jar!/META-INF/resourcesresolving 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 customResourceResolver. 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 byClassLoader#getResource(). To include the JAR file in the classpath scan of JSF, you’d need to include a JSF 2.x compatiblefaces-config.xmlfile in the/META-INFfolder of the JAR file. The same story applies to@ManagedBean,@FacesValidator,@FacesConverter,@FacesComponentand 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.xmlfile 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-INFfolder has to go in Java source folder. Theweb-fragment.xmlfile 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
ResourceResolveris the most reliable approach.