How to read Freemarker Template files from src/main/resources folder?
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
Freemarker templates placed under src/main/resources should be loaded from the classpath, not from a source-code path on disk. That distinction matters because src/main/resources exists during development, but after packaging the application into a JAR, those files are no longer regular source files.
If you configure Freemarker to read from the classpath, the same code will work in your IDE, during tests, and in production deployments. That is the reliable pattern to aim for.
Put Templates Under a Clear Resource Root
A common project layout looks like this:
The important part is choosing one template root, such as templates, and keeping all .ftl files under it. Freemarker will then resolve template names relative to that root.
Load Templates from the Classpath
In plain Java, the simplest configuration is setClassForTemplateLoading or setClassLoaderForTemplateLoading.
This tells Freemarker to search the classpath for templates/invoice.ftl. You do not pass src/main/resources/templates/invoice.ftl because that is a build-time directory, not the runtime resource path.
Render a Template After Loading It
Once the configuration is set up, rendering works the same way regardless of whether the application is running from an IDE or from a packaged artifact.
If the template contains Hello ${name}!, the output will be Hello Ada!.
Using setClassForTemplateLoading
If you prefer, you can load relative to a specific class instead of the thread context class loader:
This is also a good option. The main rule is the same: use a classpath root, not a filesystem path that depends on the project being unpacked.
Why Filesystem Paths Break
This is the mistake many examples make:
It may work locally because the source tree is present. It usually breaks when the application is packaged and deployed, because the templates now live inside a JAR rather than an accessible folder on disk. Filesystem loading is only appropriate when you intentionally keep templates outside the application artifact.
Spring Boot Note
If you are using Spring Boot with the Freemarker starter, Boot already defaults to classpath template loading. In that case, put templates under src/main/resources/templates and let the framework wire the loader. Manual configuration is more common in plain Java or custom setups.
Common Pitfalls
- Passing
src/main/resources/...to Freemarker instead of the runtime classpath path. - Mixing
setDirectoryForTemplateLoadingwith packaged JAR deployments and expecting it to keep working. - Choosing one template root in code but storing templates under a different resource folder.
- Forgetting to set
UTF-8, which can produce garbled output for non-ASCII text. - Swallowing template exceptions and making missing files or missing model keys harder to debug.
Summary
- Templates under
src/main/resourcesshould be loaded from the classpath at runtime. - Use
setClassLoaderForTemplateLoadingorsetClassForTemplateLoadingwith a clear root such astemplates. - Request templates by names relative to that root, such as
invoice.ftloremail/welcome.ftl. - Avoid filesystem paths unless the templates are intentionally external to the application.
- With classpath loading, the same Freemarker code works in development, tests, and packaged deployments.

