Building Web Content Jars for Spring Boot with Gradle

The Javascript world contains a rich ecosystem of tools for building and testing web applications.

In this post, I will show you how you can use content jar files to separate the front-end development experience for your Spring Boot projects while still keeping your deployments simple.

The idea here is pretty simple. We want to build front-ends with tools like Yeoman for code generation, Karma / Protractor for testing, Grunt / Gulp for building and Bower for dependency management.

However, we might want to deploy our HTML/Javascript code inside of our Spring Boot app instead of a CDN. We might want Spring Boot to pass in some parameters to our application. Perhaps we’re using Spring Security and want to make sure unauthenticated access to our single page app redirects to Spring Boot backed pages. Maybe we’re too cheap to set up a CDN and Run.pivotal is just giving away traffic for free.

Instead of trying to make our codebase manage both our front-end code and the server-side code, we can simply use a content jar to encapsulate most of our front-end code and include it for development using Gradle.

The concept here is pretty much identical to WebJars. Except that webjars still expect your front-end to live within your Spring Boot project, where in this solution we’re taking advantage of Spring Boot’s static content support to make as much of our UI code independent.

The Process

The process looks like this:

Screenshot 2014-03-13 21.09.26

We take our front end code and build out our deployables using the entire suite available to JavaScript tooling. We can even take advantage of IDEs like WebStorm for this.

After we have a tested front-end that we are happy with, we use the Gradle Webjar task to take our code and put it into a Jar file. Deploy this jar and now any Spring Boot app can use it.

Building an UI

For example, we create a web application using the yeoman angular generator:

mkdir blah && cd blah
yo angular
grunt --force

This makes a fully minified AngularJS application in the dist directory.

Creating a content jar

We then make this into a gradle project by calling

gradle init

We modify the build.gradle file to contain the following:

apply plugin: 'java'

task webjar(type: Jar, dependsOn: "jar") { 
    from(fileTree("dist")) {  
        into "META-INF/resources" 
    } 
}

Basically, we’re making a jar file and putting all the resources into the META-INF/resources directory.

Here, we’re taking advantage of Spring Boot’s default behaviour of serving static resources that are located within the following locations:

  • /META-INF/resources/
  • /resources/
  • /static/
  • /public/

We can generate a jar file now by calling

./gradlew webjar

We now have a content jar that contains our entire deployable front-end.

You should see a file within your build/libs directory called blah.jar. If you inspect the contents, you’ll see that all the files that you have added there are available to you.

You can publish this jar to your private repos or to Bintray. See directions for Bintray via the Gradle plugin.

Using the content jar
The content jar is just another dependency that you add to your Spring Boot project like a Jar file.

Create a new file called myapp.groovy

Add the following content:

@Grab('blah.jar dependency definition')
@Controller class myApp {}

If you have the spring boot cli installed, you should be able to run it via:

spring run myapp.groovy

If you hit the localhost:8080, you should see your yeoman app running.

To deploy to Cloud Foundry, just call

spring grab *.groovy
cf push

Summary

By using content jars, we can separate our front-end code from our Spring Boot microservices at development time while still keeping a single deployable artifact. It provides a viable solution for using the best tools for UI development while keeping server side generated code at a minimum.

It also means we can stay the hell away from Thymeleaf. Everyone wins when we don’t use Thymeleaf.

6 thoughts on “Building Web Content Jars for Spring Boot with Gradle

  1. Pingback: Spring Boot and Webjars – overwriting configuration during runtime | Tomás Lin's Programming Brain Dump

  2. Pingback: Fix Content.jar Errors - Windows XP, Vista, 7 & 8

  3. Rui Lopes

    We wouldn’t need Thymeleaf if the web was not this horrible mess you’re describing.
    The problem is the horrible toolchains required to do web development.

    But when you’re stuck into it, and probably earning money from it on a day to day basis, I guess it’s hard to take perspective and consider that the content of this blog post, full of tools, setups, yo blahs, foos –help and bars –shit-forgot-options are the very reason why Thymeleaf is so popular.

    Reply

Leave a comment