; last updated - 7 minutes read

Fork me on GitHubRecently 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.

Experiences with Spring Boot: efficiency

All in all working with Spring Boot was a pleasant experience. From a developers perspective working with a simple Java program is a lot simpler and a lot more efficient than working with an application server. For one, you can almost always rely on hot code replacement. Modern IDEs go to great lengths to make hot code replacement possible in a server environment, but since this is not a trivial task they often fail (unless you're using Tomcat).

An important (and often underestimated) aspect of development efficiency is server startup time. On my desktop machine, Spring Boot starts a PrimeFaces application in roughly 3 seconds. Running the same application on Tomcat takes roughly 7 seconds - still a good time, but you'll notice the difference. By contrast, starting Glassfish on the same machine take 30 seconds, and starting Liferay 6.2 takes several minutes.

My early estimation is work with Spring Boot is more efficient than work with Glassfish or Liferay, even if they're combined with JRebel (a highly recommended commercial tool improving hot code replacement). Plus, you can still add JRebel, giving you an additional boost.

Experiences with Spring Boot: simplicity

As for simplicity, I'd say Spring Boot is just great. Spring Boot offers a default configuration mode, trying to guess the entire configuration from the available classes and files. By default, Spring Boot prefers the new Java configuration style over the old XML configuration files. Such a configuration can be as simple as this:

@Configuration @ComponentScan(basePackages={""}) @EnableAutoConfiguration public class Main extends SpringBootServletInitializer { public static void main(String[] args) { SpringApplication.run(Main.class, args); } @Override protected SpringApplicationBuilder configure( SpringApplicationBuilder application) { return application.sources(Main.class); } }

This file replaces both the web.xml and the Spring configuration file! To add a servlet, you add a method to the main class (instead of configuring it in the obsolete web.xml). For instance, the Servlet running JSF is configured like so:

public class Main extends SpringBootServletInitializer { ... @Bean public ServletRegistrationBean servletRegistrationBean() { FacesServlet servlet = new FacesServlet(); ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(servlet, "*.jsf"); return servletRegistrationBean; } ... }

However, I had my difficulties finding out how to do more advanced configurations. JSF applications, in particular, seem to be a bit odd. They require both web.xml and the Java config classes. Omit one of them, and JSF won't start. Luckily one of my readers helped me to find out how to set the context parameters. Thank you very much, Robbe64! Here's what to do:

First, you need a second configuration class. Let's call it Initializer:

@Configuration public class Initializer implements ServletContextInitializer { @Override public void onStartup(ServletContext sc) throws ServletException { sc.setInitParameter("primefaces.CLIENT_SIDE_VALIDATION", "true"); sc.setInitParameter("javax.faces.PROJECT_STAGE", "Development"); } }

To activate both configuration classes, modify the configure method by adding the Initializer class:

@Configuration @ComponentScan(basePackages={""}) @EnableAutoConfiguration public class Main extends SpringBootServletInitializer { ... @Override protected SpringApplicationBuilder configure (SpringApplicationBuilder application) { return application.sources( new Class[] { Main.class, Initializer.class}); } ... }

GitHub has the full source code at the tiny PrimeFaces 5 Client Side Bean Validation demo.

faces-config.xml

Luckily adding setting to faces-config.xml works flawlessly. The demonstrate the point, I added two JSF custom scopes and a JSF navigation handler.

Dependency injection

Yeah, it isn't hard to guess: Spring Boot runs on Spring. So you can use everything Spring offers in your JSF application. If you're into CDI, you're out of luck: they didn't create Spring Boot for you. The article I already mentioned at the beginning (Application Servers are dead! (Sort of)) shows you a couple of alternatives to Spring Boot.

If you stick to Spring, you ought to consider not to use @ManagedBeans at all. Add the SpringELResolver to the faces-config.xml, and you can use Spring Beans instead of JSF beans. I demonstrate this approach in several examples of the advanced template project.

Gradle

Gradle is an alternative and a successor to both Maven and Ant. It offers both a declarative style and a programming API. Most examples on the internet only cover the declarative style, but it's perfectly possible to add an if statement in a Gradle build file. In fact, that's the big advantage of Gradle. The template projects use this feature to switch dynamically between the Mojarra libraries and Apache MyFaces. That's such an interesting feature that I'll dedicate a few lines to it, even if it's not the topic of the article. At the beginning of the Gradle build file I defined a boolean variable:

boolean useMyFaces=true

In the dependencies section, we can use this variable to chose between configuration - just the way you're used to as a Java (or Groovy) programmer:

dependencies { if (useMyFaces) { compile 'org.apache.myfaces.core:myfaces-api:2.2.4' runtime 'org.apache.myfaces.core:myfaces-impl:2.2.4' } else { compile 'com.sun.faces:jsf-api:2.+' runtime 'com.sun.faces:jsf-impl:2.+' } }

Try to do the same in Maven or Ant! It's possible, but it's not as simple.

Most of the time, using Gradle is a pleasant experience. Only if you're using a very complex project (such as a multiproject), or exotic projects such as Liferay portlets, you should be careful about using Gradle. Maven has been around for a long time, it's widespread and it's more mature the Gradle, so the IDE integration is a lot better. However, Gradle is catching up rapidly. The only disadvantage I saw (if it is one) is I had to install the entire Spring Tool Suite just to use the Gradle plugin. There used to be a stand-alone Gradle plugin for Eclipse, but it seems to have vanished. In any case, installing STS in a Spring Boot project makes sense, anyways.

Summary

Traditionally, I'm not exactly a friend of Spring. Too much XML, too much hidden configuration, and too "enterprisey".[1] However, Spring Boot, the new annotation style, and the Java config make Spring attractive to me again. I'm still fond of CDI, but Spring caught up recently. Spring Boot, in particular, is definitely worth a look.


simple PrimeFaces 5 project on Spring Boot

a PrimeFaces 5 project using Client Side Bean Validation (also illustrates how to set context parameters)

PrimeFaces, Spring Boot, JSF custom scopes and Spring custom scopes.

Spring Boot Reference Guide (Version 1.1.4)

StackOverflow on JSF + Spring Boot

Application Servers are dead! (Sort of)


  1. That's quite ironic, given Spring started as a light-weight alternative to the heavy enterprise-level J2EE solutions.↩

Comments