Over a million developers have joined DZone.

"Bootiful" Java EE Support in Spring Boot 1.2

· Java Zone

The Java Zone is brought to you by Stormpath—offering a pre-built Identity API for developers. On 11/3 at 10AM PT, join Stormpath Developer Evangelist, Micah Silverman, to dive deep into using JWTs to protect microservices from CSRF and more. Register here!

Originally written by Josh Long  on the SpringSource blog.

In this blog, I want to look at - and demonstrate - some of the many new features in Spring Boot 1.2 that make the lives of those coming from, or otherwise building on, Java EE easier.

It's worth mentioning that a lot of this support has been possible with Spring before, of course, but now with Spring Boot 1.2, it's just so darned easy!

First, here's an example program with notes after.

package demo;

import org.glassfish.jersey.jackson.JacksonFeature;
import org.glassfish.jersey.server.ResourceConfig;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.jms.annotation.JmsListener;
import org.springframework.jms.core.JmsTemplate;

import javax.annotation.PostConstruct;
import javax.inject.Inject;
import javax.inject.Named;
import javax.jms.JMSException;
import javax.persistence.*;
import javax.transaction.Transactional;
import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
import java.io.Serializable;
import java.util.Collection;
import java.util.logging.Logger;

public class Application {

  public static class JerseyConfig extends ResourceConfig {

    public JerseyConfig() {

  public static class GreetingService {

    private JmsTemplate jmsTemplate;

    private EntityManager entityManager;

    public void createGreeting(String name, boolean fail) {
      Greeting greeting = new Greeting(name);
      this.jmsTemplate.convertAndSend("greetings", greeting);
      if (fail) {
        throw new RuntimeException("simulated error");

    public void createGreeting(String name) {
      this.createGreeting(name, false);

    public Collection<Greeting> findAll() {
      return this.entityManager
      .createQuery("select g from " + Greeting.class.getName() + " g", Greeting.class)

    public Greeting find(Long id) {
      return this.entityManager.find(Greeting.class, id);

  public static class GreetingEndpoint {

    private GreetingService greetingService;

    public void post(@QueryParam("name") String name) {

    public Greeting get(@PathParam("id") Long id) {
      return this.greetingService.find(id);

  public static class Greeting implements Serializable {

    private Long id;

    public String toString() {
      return "Greeting{" +
      "id=" + id +
      ", message='" + message + '\'' +

    private String message;

    public String getMessage() {
      return message;

    public Greeting(String name) {
      this.message = "Hi, " + name + "!";

    Greeting() {

  public static class TestCommandLineRunner {

    private GreetingService greetingService;

    public void afterPropertiesSet() throws Exception {
      try {
        greetingService.createGreeting("Josh", true);
        } catch (RuntimeException re) {
          Logger.getLogger(Application.class.getName()).info("caught exception...");

    public static class MessageProcessor {

      @JmsListener(destination = "greetings")
      public void processGreeting(Greeting greeting) throws JMSException {
        System.out.println("received message: " + greeting);

    public static void main(String[] args) {
      SpringApplication.run(Application.class, args);

The rest of the code, application.properties and the Maven build, are available online.

JAX-RS with Jersey

The example demonstrates JAX-RS integration (in this case, using Jersey 2.x) in thedemo.Application.GreetingEndpoint. Note how convenient it is to get it all working! The only thing to be weary of is that you need to specify a ResourceConfig subclass to let Jersey know which components to register.

Global Transactions with JTA

It demonstrates global transactions (a.k.a., XA) with the new auto-configured JTA support. To do this, we've used the Atomikos standalone JTA provider. We could have as easily used Bitronix, as well; both are auto-configured if you bring the appropriate starter along. In this example, in the GreetingService, JMS and JPA work is done as part of a global transaction. We demonstrate this by creating 3 transactions and simulating a rollback on the third one. You should see printed to the console that there are two records that come back from the JDBCjavax.sql.DataSource data source and two records that are received from the embedded JMS javax.jms.Destination destination.

The Undertow embedded web-server

This example also uses the Wildfly (from RedHat) application server's awesome Undertow embedded HTTP server instead of (the default) Apache Tomcat. It's as easy to use Undertow as it is to use Jetty or Tomcat - just exclude org.springframework.boot:spring-boot-starter-tomcat and add org.springframework.boot:spring-boot-starter-undertow! This contribution originated as a third-party PR - thanks Ivan Sopov! It's awesome.

Odds and Ends

Just for consistency, the example also uses JSR 330. JSR 330 describes a set of annotations that you can use in proprietary application servers like WebLogic as well as in a portable manner in dependency injection containers like Google Guice or Spring. I also use a JSR 250 annotation (defined as part of Java EE 5) to demonstrate lifecycle hooks.

This example relies on a Spring Boot auto-configured embedded, in-memory H2javax.sql.DataSource and - a Spring Boot auto-configured embedded, in-memoryHornetQ javax.jms.ConnectionFactory. If you wanted to connect to non-embedded instances, it's straightforward to define beans that will be picked up instead.

This example also uses the new @SpringBootApplication annotation which combines@Configuration@EnableAutoConfiguration and @ComponentScan. Nice!


Though I'm using a lot of fairly familiar Java EE APIs, this is still just typical Spring Boot, so by default you can run this application using java -jar ee.jar or easily deploy it to process-centric platforms-as-a-service offerings like - Heroku or Cloud Foundry. If you want to deploy it to a standalone application server like (like Apache Tomcat, or Websphere, or anything in between), it's straightforward to convert the build into a .war and deploy it accordingly to any Servlet 3 container.

If you deploy the application to a more classic application server, Spring Boot can take advantage of the AS's facilities, instead. For example, it's dead-simple to consume a JNDI-bound JMS ConnectionFactoryJDBC DataSource or JTA UserTransaction.

Spring Boot 1.2: Choice and Power

I, personally, would question a lot of these APIs. Do you really need distributed, multi-resource transactions? In today's distributed world, consider global transaction managers an architecture smell. Do you really need to use JAX-RS when Spring offers a richer, integrated Spring MVC-based stack complete with MVC, REST, HATEOAS, OAuth and websockets support? It might well be that you do, and - as always - the choice is yours. That's why this release is so cool! More power, more choice.

What Else?

lot, actually. There are a slew of new features. I couldn't even begin to cover them all here. So I won't try. Check out the release notes for the full scoop!

Spring Boot 1.2 is fast approaching GA, and now's a very good time to try the bits, kick the tiresfile issues and ask questions!

Building Identity Management, including authentication and authorization? Try Stormpath! Our REST API and robust Java SDK support can eliminate your security risk and can be implemented in minutes. Sign up, and never build auth again!


Published at DZone with permission of Pieter Humphrey, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

The best of DZone straight to your inbox.

Please provide a valid email address.

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}