The Move from Velocity to FreeMarker with Spring Boot

You may recall that we recently upgraded NixMash Spring from Spring Boot 1.3.5 to 1.4.0, which is when we learned that Velocity Templating support was being phased out in favor of FreeMarker. It wasn't on the schedule or the roadmap, but templating plays an integral part in a number of site functions so we made the move from Velocity to FreeMarker our top Spring Boot 1.4.0-specific priority.

We had quite a few templates to migrate to FreeMarker as you can see.

The Process

Template by template, copying a Velocity VM from its /resources area to an .FTL file in a corresponding FreeMarker folder, recreate its loading method in new FreeMarker Service classes, then write the test. Each test was pretty simple and looked a lot like this test for the FreeMarker-generated /robots.txt file.

Two New Service Classes with “Fm” prefixes replaced the existing TemplateService and MailService classes. All of the templates were migrated and their supporting Service Layer methods were created. Each template had its corresponding passing @Test so we knew we could move to Phase Two: replacing calls from various locations to the existing Velocity-based Service classes with calls to the new FmService and FmMailService classes. The work consisted of swapping out Spring Beans mostly. Test updates followed and we were soon on the home stretch!

Excellent Exception Messages

Here's something great about FreeMarker, its console exception messages are really helpful for developers getting up to speed with its syntax. No, not just helpful, SUPER helpful!

The above output was the Template Exception message produced by the following Java catch{} on loading a template.

} catch (IOException | TemplateException e) {
logger.error("Problem merging Robots.txt template : " +

Template Syntax Differences

There are a lot of little syntax differences between Velocity and FreeMarker, but overall the two templating engines are very similar. I found Velocity to be very capable, and FreeMarker is certainly just as capable if not more so. Below is a simple comparison generating a list, with FreeMarker on top and Velocity below. Migrating the templates from Velocity to FreeMarker really wasn't painful at all. Now, if there were 100's of templates to rewrite, that might generate a bit more pain. Again, the FreeMarker Exception Messages were really helpful.

IntelliJ Rocks FreeMarker

I guess this is more of a sidebar, but IntelliJ IDEA fully supports FreeMarker as you can see below with Implicit Variable Declarations and Intellisense. No surprise there, since IntelliJ Rocks in general.

Loading Templates

The FreeMarker process of populating and loading templates is very similar to Velocity. After working with them both I would say FreeMarker is cleaner.

FreeMarker and Thymeleaf, Together

FreeMarker is designed to be a fully capable MVC View Resolver out of the box in Spring Boot. Pretty much auto-configuration for both, which is the good news. The downside of all of that autoconfig goodness is that FreeMarker is going to tussle with Thymeleaf to be your MVC View Resolver and your Logging Output will look a lot like this.

Don't worry, the fix is really simple. Here are the properties I added to the /mail module's Spring .properties file. (Templating takes place in the NixMash Spring Mail module, one of several modules that comprise the project.) The key property to make all of the above noise go away and turn MVC View Resolution over to Thymeleaf is spring.freemarker.enabled=false.

That will get you 95% of the way home on silencing the FreeMarker logger on MVC Requests. I noticed when using FreeMarker for non-Thymeleaf display pages like /robots.txt the logger would kick back in.

The solution here is to know that FreeMarker uses SLF4J Logging, so being armed with that info from the excellent FreeMarker Docs we can whip up a file.

Deprecated No Longer!

Taking the time to move from Velocity to FreeMarker was definitely worth it. It feels good to not have to annotate the Template Service Classes with @SuppressWarnings(“deprecation”) and to know we're ready for Spring Boot 1.5, whenever that day may come. In the meantime we'll share any cool FreeMarker discoverings with you!

Source Code Notes for this Post

All source code discussed in this post can be found in my NixMash Spring GitHub repo and viewed online here.

Posted September 14, 2016 08:34 PM EDT

More Like This Post