As I wrote earlier, it’s actually pretty simple to redirect facelet resolving to JARs. As JSF already includes mechanisms for scanning for JSF beans in JARs, this could enable a very simple approach for modularizing deegree’s JSF codebase.
So far, so good. But wait! deegree’s workspace (configuration) concept allows for putting JARs into module folder to add functionality dynamically (without messing with the deegree webapp) to an existing deegree web service deployment. Currently, this is in use for WPS processes, additional feature store implementations, filter functions, etc. Wouldn’t it be nice to to be able to plug in JSF functionality dynamically by simply putting it into a deegree workspace?
Unfortunately, it seems that this is not possible at the moment 😦
The main problem is that loading code from deegree’s workspace involves a custom classloader. And an even harder problem: it’s vital that deegree workspaces can be started and stopped dynamically, so an administrator can make changes (or even exchange the full workspace) without restarting the deegree webapp in the servlet container. Some details:
- It’s actually no big deal to retrieve facelets (*.xhtml files) using a custom classloader (such as deegree’s workspace classloader, that takes the JARs below folder modules into account).
- It’s apparently impossible to add new JSF beans without restarting the whole webapp. The JSF 2.0 specification (section 11.4.2) is pretty clear about the fact, that scanning for JSF annotated classes only happens once on startup of the system. After investigating Mojarra’s (the reference implementation of Java Server Faces) source code a bit more, I found the AnnotationProvider extension point, but this would be vendor specific and not allow for exchanging JSF bean classes after initialization (webapp startup). While hacking around, I even realized that the JSF bean scanning obviously occurs on Servlet instantiation (not initialization), so it’s not possible to force deegree’s servlet to be initialized first using the load-on-startup parameter. This would at least have opened the door to adding JSF modules from the modules directory of the startup workspace…
To conclude: modularizing JSF components into JARs and putting them into WEB-INF/lib is one thing. Loading them using a custom classloader and allowing for code replace after webapp initialization is another — and probably not so easy.
I found some hints on the web that is is possible to OSGify JSF — so maybe moving to an OSGi container would be an option. Another thing which may be worthwhile to look at could be the so-called web fragments introduced by Servlet specification 3.0.