JSF 2.2 and PrimeFaces 5 on Spring Boot

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 into 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;
    }
    ...
}

… but …

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 in 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 spend 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, to much hidden configuration and too “enterprisy”.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.


The template projects:

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.

Dig deeper:

Spring Boot Reference Guide (Version 1.1.4)
StackOverflow on JSF + Spring Boot
R.I.P. XML in Spring Applications
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.

14 thoughts on “JSF 2.2 and PrimeFaces 5 on Spring Boot

  1. Malte

    Hi,

    I am also trying to get a JSF app running with Spring Boot.

    Did you ever try to create a runnable jar and access your webservice?
    Any hints on how to link the *.xhtml resources?

    Reply
    1. Stephan Rauh Post author

      I’m told Spring Boot has been designed with microservices in mind, so creating a web service (be it REST or SOAP) should be easy. But I didn’t do it myself yet.

      As for the xhtml files: Could you elaborate, please? Webservices don’t need XHTML resources, and the demo on GitHub uses a fairly standard configuration in the web.xml to display the xhtml file as JSF view.

      Reply
      1. Malte

        Hi,
        sorry maybe I wasn’t clear enough.
        Actually I am trying to create a JSF App with Spring boot.
        In order to assemble the application I am using Gradle.
        As long as I am developing I am running the app by calling gradle bootRun. After the server started I am able to access my app in the browser. All fine.

        Next step is now, to deploy the app. Since I want to use the embedded tomcat I am calling Gradle distTarwhich assembles everything and my actual application is packaged as JAR.
        I am running the app with the assembled run script and tomcat is powering up and spring boot tells me, again in the log, “All fine I am running” ;-).

        BUT, as soon as I try to access the app, I am getting a 404 Not Found.

        Reply
        1. Stephan Rauh Post author

          Hi Malte,

          for some reason your comment was lost in the spam folder. I hope my late answer reaches you nonetheless.

          Your problem sounds a bit weird. I don’t know distTar, but judging from the documentation, everything should run fine. Obviously, it does, according to your log. Probable there’s a configuration problem. Maybe your application runs in under different context name, or doesn’t start at all. Chances are you log message only says the application container is up and running, but not necessarily the application.

          But all that is guesswork. Can you provide some source code (maybe on GitHub) so I can have a look at it?

          Regards,
          Stephan

          Reply
          1. Malte

            Hi Stephan,

            distTar is a task the spring-boot plugin for gradle ships with.

            It can be used to create a tar ball which can be executed.
            I created a small example, just check it out and run “gradle distTar”

            In the bin folder you will find the run skript.
            You will see that, as soon as u access the index.xhtml a 404 will be shown.

            BR

          2. Stephan Rauh Post author

            Hi Malte,

            when I tried your example, Eclipse offered me another Gradle task that seems to fit better. Try “gradle bootRun” or “gradle bootRepackage”. When I examined the resulting jar files, I notice a different folder setup, which may explain your difficulties (or rather, Spring’s difficulties):

            gradle distTar gradle bootRepackage
  2. bilak

    Hello Stephan,
    spring boot works well with primefaces (I’m currenty using 5.2 version), but I’m not able to get fileupload working (I tried all 3 options auto|native|commons). Don’t you have some experience with fileUpload (if so can you update your github project with this)?

    Thanks

    Reply
  3. pvy centrum cz

    If you prefer to use java configuration of FacesServlet over web.xml, you need to add the parameter:

    sc.setInitParameter("com.sun.faces.forceLoadConfiguration", "true");

    Reply
  4. Marcelo Romulo Fernandes

    Hi everyone,

    I’ve created JSF Spring Boot Starter at https://github.com/persapiens/jsf-spring-boot-starter
    This open source project enables JSF usage inside JAR packaged Spring Boot Application.
    It autoconfigures PrimeFaces, OmniFaces, Mojarra and MyFaces libraries to run at embedded Tomcat, Jetty or Undertow servlet containers.
    It also aims to solve JSF and Spring Boot integration features. Current version includes JSF and CDI annotations support and Spring Security JSF Facelet Tag support.

    Collaboration is welcome.

    Reply
  5. Ahmed Ibrahim

    Hi,

    I’m using spring boot with web.xml defined in the application configuration and everything is working fine without the need to set extra configuration.

    Reply

Leave a Reply

Your email address will not be published.