Freemarker 在 maven 生成的 jar 中加载模板的位置

Where does Freemarker load templates in a maven generated jar

让我澄清一下我目前的做法。我有一个 Maven 项目,包架构如下所示:
src/main/java/com/gearon/app/App.java
src/main/java/com/gearon/app/configuration/Config.java
src/main/java/com/gearon/app/datamodel/*.java

我尝试使用以下代码在 Config.java 中设置加载模板的目录:

    cfg = new Configuration();
    cfg.setClassForTemplateLoading(Config.class, "/templates");
    cfg.setDefaultEncoding("UTF-8");
    cfg.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);

我已将模板放在 src/main/java/com/gearon/app/templates
下 架构是src/main/java/com/gearon/app/templates/*.ftl

如果我 运行 直接用 main 方法编写代码,效果很好。但是,当我将项目打包成 jar 时,它无法加载模板,错误如下所示:

java.io.FileNotFoundException: Template "index.ftl" not found.

我想知道将这些模板放在哪里。

嗯,基于对 Freemarker official site

手册的研究

void setClassForTemplateLoading(Class cl, String basePackagePath) and void setClassLoaderForTemplateLoading(ClassLoader classLoader, String basePackagePath): These are for when you want to load templates via the same mechanism with which Java loads classes (from the class-path, as they used to say vaguely). This is very likely be the preferred means of loading templates for production code, as it allows you to keep everything inside the deployment jar files. The first parameter decides which Java ClassLoader will be used. The second parameter specifies the package that contains the templates, in /-separated format. Note that if you don't start it with /, it will be interpreted relatively to the package of the Class parameter.

注释很重要:

Note that if you don't start it with /, it will be interpreted relatively to the package of the Class parameter.

变更后
cfg.setClassForTemplateLoading(Config.class, "/templates");

cfg.setClassForTemplateLoading(Config.class, "templates");

一切正常,就像魅力一样。