Friday, August 28, 2009

Spring Faces sample project

I recently put together a sample of Impala working with Spring Faces, that is, the combination of Spring Web Flow and JSF. The example is based on the Spring Faces flagship sample, a hotel booking application which uses JSF for persistence, and Spring Security for authentication/authorization.

See instructions on how to run the sample on the Impala wiki.

I have to confess that none of the technologies used in this sample are personal favourites - I'm much more inclined towards Spring MVC, Hibernate on its own, and a more straightforward templating technology like Freemarker for the view layer. That being said, it was an interesting exercise, which threw up some interesting challenges, and also important to verify that Impala could work nicely with each of these technologies without a gargantuan amount of effort on the user's part.

One of these challenges was figuring out how to set up the JSF runtime to be loaded up by the module class loader, rather than the application class loader.

More significant for the evolution of Impala itself was figuring out how to create an arbitrary mapping from the request URI path prefix (the part of the URL after the host, port and application name), and an arbitrary module. In the Spring Faces sample, I needed to map all requests with a prefix of /spring and no extension (e.g. .htm) in the path to the web module containing the Web Flow definitions and faces view. This particular requirement gave me the push I needed to implement the main features coming in the next drop of Impala, that is, the ability to map from arbitrary URI path prefixes to modules, and once within a module, to map individual requests to servlets or filters, themselves defined within the module, based on the URI extension.

The Impala Spring Faces stack is somewhat experimental, but it does offer the promise of truly modular, dynamically reloadable applications based on these technologies.

Outstanding issues
There are a few wrinkles outstanding, though. The Spring web flow long running transaction is still not working. I have added a flush() call so that the booking does persist, but this happens at the time the booking is first entered rather than confirmed. Also, it does seem possible at least in some situations to make simple changes to the flow definitions and reload these without preventing the completion of existing flows, but I'm sure there are some corner case