03 June 2014

It is pretty simple to spin up a micro REST service using Spring Boot and Jersey 2.x. In fact, there are various tutorials out there that show how this can be done with very little code/configuration:

Jersey 2.x also provides a nice Spring support module, which makes it easy to register Jersey 2.x resources as Spring components. The first step is to create a Spring-based Jersey 2.x resource configuration:

JerseyConfig.java
import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.server.spring.SpringComponentProvider;
import org.glassfish.jersey.server.spring.scope.RequestContextFilter;
import org.springframework.stereotype.Component;

@Component
public class JerseyConfig extends ResourceConfig {

    public JerseyConfig() {
        register(MyResource.class);
        register(RequestContextFilter.class);
        register(LoggingFilter.class);
        register(SpringComponentProvider.class);
    }
}

Once you have the configuration created (and Spring set up to component scan it at startup up), you also need to create a servlet to register the configuration with Jersey 2.x:

ApplicationConfig.java
import java.io.IOException;

import org.glassfish.jersey.servlet.ServletContainer;
import org.glassfish.jersey.servlet.ServletProperties;
import org.springframework.boot.context.embedded.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration
@ComponentScan({"com.test"})
public class ApplicationConfig {

    @Bean
    public ServletRegistrationBean jerseyServlet() {
        final ServletRegistrationBean registration = new ServletRegistrationBean(new ServletContainer(), "/api/*");
        registration.addInitParameter(ServletProperties.JAXRS_APPLICATION_CLASS, JerseyConfig.class.getName());
        return registration;
    }
}

This is pretty simple, but when you start up the application and then make a call to your REST resource, you may notice that Jersey 2.x is not initialized until this first call:

2014-05-19 12:08:30.062  INFO 8626 --- [lication.main()] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 8080/http
2014-05-19 12:08:30.065  INFO 8626 --- [lication.main()] com.test.Application        		      : Started Application in 13.461 seconds (JVM running for 21.588)
2014-05-19 12:10:29.363  INFO 8626 --- [lication.main()] o.g.jersey.server.ApplicationHandler     : Initiating Jersey application, version Jersey: 2.7 2014-03-12 18:11:31...

This means that the first request to your service incurs the cost of initializing Jersey 2.x. Luckily, there is a simple fix that will ensure that Jersey 2.x is initialized on startup. We can add a call to the setLoadOnStartup() method of the ServletRegistration instance in our Spring configuration to ensure that Jersey 2.x is initialized upon application start up:

ApplicationConfig.java
import java.io.IOException;

import org.glassfish.jersey.servlet.ServletContainer;
import org.glassfish.jersey.servlet.ServletProperties;
import org.springframework.boot.context.embedded.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration
@ComponentScan({"com.test"})
public class ApplicationConfig {

    @Bean
    public ServletRegistrationBean jerseyServlet() {
        final ServletRegistrationBean registration = new ServletRegistrationBean(new ServletContainer(), "/api/*");
        registration.addInitParameter(ServletProperties.JAXRS_APPLICATION_CLASS, JerseyConfig.class.getName());
        registration.setLoadOnStartup(1);
        return registration;
    }
}

After the change above, the Jersey application is initialized prior to application start:

2014-05-19 12:10:29.363  INFO 8626 --- [lication.main()] o.g.jersey.server.ApplicationHandler     : Initiating Jersey application, version Jersey: 2.7 2014-03-12 18:11:31...
2014-05-19 12:10:30.062  INFO 8626 --- [lication.main()] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 8080/http
2014-05-19 12:10:30.065  INFO 8626 --- [lication.main()] com.test.Application        		      : Started Application in 13.461 seconds (JVM running for 21.588)

comments powered by Disqus