Some time ago, I wrote about the challenges of getting JSF in a Spring Boot container up and running. The problem is that Spring Boot is officially not supported by the Mojarra team, which means it’s up to the Spring Boot team to ensure compatibility.
The Spring Boot ticket Phil Webb opened in response to my article is still open, but he pointed me to an interesting article. Alex Bath of Oakdale Software managed to run a JSF application on Apache MyFaces 2.2.6.
However, I suspect that compatibility between JSF and Spring will deteriorate more and more in the (possibly near) future. If I’m not mistaken, JSF is going to be tightly integrated with CDI, so many interesting features simply won’t work without CDI. On the long run, this may render JSF useless without CDI.
That said, I’d like you to point to the GitHub repository of the project of Alex and invite you to read the full story.
One of our BootsFaces users surprised me by reporting that his application ceased to work after updating to Mojarra 2.2.11. After some investigation, I found out that the Mojarra team had implemented something that looked like an optimization. It works fine on a traditional Tomcat, but it doesn’t on Spring Boot.
After reporting the bug to the Mozilla team, I learned two things:
- Spring Boot is not officially supported by the Mojarra team. They’ll accept your bug fixes happily, but they’re reluctant to fix bugs related to Spring Boot themselves. Now, that shouldn’t come as a surprise. Spring considers itself as a competitor to JavaEE, so it’s just a happy coincidence that it’s possible to combine Spring Boots and JSF.
- There was a good reason to implement the breaking change, and it wasn’t performance.
Let’s bust a myth. There are very good reasons to use CDI or Spring, but dependency injection isn’t one of them. There are a lot of alternatives. And I’m not talking about Google Guice, although that’s a very fine DI framework indeed. Why don’t we write our own DI framework? Can’t be difficult, can it?
It’s true: today’s open source libraries make writing your own DI framework incredibly simple. But even without such a library writing a DI framework isn’t difficult (at least if you’re ready to learn something about class loaders). I’ll develop a sketchy DI framework in this article. In theory, you could finish my work to implement a full-blown DI container and put it into production. Even if you don’t, you’ll understand how CDI and Spring work after reading this article.
But first I’d like to present you an alternative you’re probably not aware of.
Recently I reported about Spring Boot (see Application Servers are dead! (Sort of)), an interesting approach to embed your application server into your application instead doing it the other way round.
However, Spring Boot is a fairly new technology, so the documentation is still work in progress. Most of the documentation is great, but there are still sentences like
Applications that are not already Spring applications might be convertible to a Spring Boot application, and the guidance above might help, but your mileage may vary.
Most JSF applications clearly fall into this category. So I’ve prepared a JSF template project to spare you some of the mileage. Currently there’s a simple simple PrimeFaces project and a more advanced project demonstrating Spring and JSF scopes.
To make things more interesting, I added Gradle and JSF custom scopes to the equation.
Oops. We did it again. We heeded the consultants advice once again.
You shouldn’t do that, you know. Not thoughtlessly, that is. It’s all right to call a consultant and listen to his advice. But don’t you follow his advice blindly. If he’s a good consultant, most of his advice is good. But every once in a while it’s just poisoned. A consultant’s job is to spread idea’s he’s already seen in other companies. In other words: he’s spreading something just above mediocrity. Respectable consultants don’t give really bad advices, but sometimes they kill good ideas they haven’t seen before – often without actually intending to do so.
An advice you definitely should not heed is to combine Spring and JSF. They simply aren’t made for each other. They aren’t exactly incompatible, but you have to split your application in two parts: JSF-land and Spring Country. Between those two countries there is a clearly defined border. Complete with fences, customs checks and everything else a frontier needs.
You’d rather use CDI with JSF. That’s a marriage made in heaven.
Unfortunately we did heed the consultants advice and abandoned CDI. Now it’s my team’s job to make the best of it.
Update (August 9, 2013)
Neill Griffin seems to have found a nice solution to the problem. Have a look at his announcement and his demo at GitHub. The solution even runs as a Liferay portlet.
Update (May 10, 2014)
Rafael Ponte reports in his comments (at the end of this article) the problem has been solved recently (Spring 3.2). He also reports it possible to avoid the serialization exception by adding the annotation
@Scope(proxyMode=ScopedProxyMode.TARGET_CLASS, value="session") to the bean. The bean has to be injected as a manged property (
@ManageProperty instead of