spring-bootfreemarker

spring-boot-starter-freemarker does not find templates


Using spring-boot-starter-freemarker without further config I would expect to be able to load templates from the default template path(src/resources/templates) (note it's src/... not build/...).

Having this file here:

src/resources/templates/emails/welcome.ftl

Trying to load it as a template:

// some service class
  @Autowired
  private Configuration freemarkerConfig;

  public void doStuff() {
    Template t = freemarkerConfig.getTemplate("emails/welcome.ftl");
    // ...
  }

Fails with this error message:

freemarker.template.TemplateNotFoundException: Template not found for name "emails/welcome.text.ftl".
The name was interpreted by this TemplateLoader: MultiTemplateLoader(loader1 = FileTemplateLoader(baseDir="/some/path/backend/build/resources/main/templates", canonicalBasePath="/some/path/backend/build/resources/main/templates/"), loader2 = ClassTemplateLoader(resourceLoaderClass=org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer, basePackagePath="" /* relatively to resourceLoaderClass pkg */)).

So the configuration seems kind of ok-ish, but instead of the src folder it is using the build folder. When running via./gradlew bootRun we see the error. Doing a ./gradlew buildand then ./gradlew bootRun the templates are found - because they are now in the build folder. But for development it would be much appreciated to not require a full re-build.

So, I know we now could configure freemarker manually to load from the src folder, but that feels hacky.

Am I doing something wrong or is this expected behavior?


Solution

  • You can configure bootRun so that sources are loaded from their source location. Assuming that the templates are part of the main source set, i.e. they're in src/main/resources, the configuration would be the following:

    bootRun {
        sourceResources sourceSets.main
    }
    

    This is described in the reference documentation for Spring Boot's Gradle plugin.