freemarker模板在jar包中路径读取失败:freemarker.template.TemplateNotFoundException: Template not found for name

问题背景

将p1整合到p0平台时候,freemarker读取jar包中模板文件失败,报错信息:freemarker.template.TemplateNotFoundException: Template not found for name "

原因排查

在p0测试服务器可复测,但在p1中未出现此问题;怀疑是安装问题导致,由于p1跟p0分别安装在服务器不同路径下, 可能跟文件路径权限有关,所以将p0安装路径改为跟p1一致,重装后测试,发现问题仍然存在,故排除安装路径问题;因为涉及模块为brick1模块,读取jar包时候路径报错,怀疑跟文件权限有关,将brick1模块jar包权限修改,重启后发现问题依然存在,故排查安装文件用户权限问题; 因为考虑到p1跟p0中业务代码一致,freemarker配置也

一致,由于p0中有其他模块也使用了freemarker,猜测可能是有更高优先级的配置,故在本地打不同产品(p0/p1)生产模式下的war包,经测试,都存在此问题,故排除其他模块配置的影响;排除影响因素外,打断点调试,在Configuration.getTempalte()方法中抛出的报错信息。从Freemarker.render()方法入手,发现初始化时候在Configuration中获取到的Template为空,继续追,发现在cache.getTemplate()时候获取到的Template为空,然后在TemplateCache 初始化时候断点测试,最终发现p0平台代码最后在FreemarkerViewMaker.make()时候,追溯发现Freemarker.initFreeMarkerConfigurer()时候加载器为FileTemplateLoader:

protected void initFreeMarkerConfigurer() throws IOException, TemplateException {
   String path = freemarkerDirectiveFactory.getFreemarker();
   File file = Files.findFile(path);
   if (!Lang.isEmpty(file)) {
      Properties p = new Properties();
      p.load(Streams.fileIn(file));
      configuration.setSettings(p);
   }
   File f = Files.findFile(prefix);
   configuration.setDirectoryForTemplateLoading(f);
}

public void setDirectoryForTemplateLoading(File dir) throws IOException {
    TemplateLoader tl = getTemplateLoader();
    if (tl instanceof FileTemplateLoader) {
        String path = ((FileTemplateLoader) tl).baseDir.getCanonicalPath();
        if (path.equals(dir.getCanonicalPath()))
            return;
    }
    setTemplateLoader(new FileTemplateLoader(dir));
}

而在读取jar包路径文件时候,应该用ClassTemplateLoader,查看p1平台代码发现,Freemarker.initFreeMarkerConfigurer()时候为MultiTemplateLoader,支持类路径加载器:

protected void initFreeMarkerConfigurer() throws IOException, TemplateException {
    Properties p = new Properties();
    String path = this.freemarkerDirectiveFactory.getFreemarker();
    File file = Files.findFile(path);
    if (Lang.isEmpty(file)) {
        p.load(Streams.wrap(this.pro.toString().getBytes()));
    } else {
        p.load(Streams.fileIn(file));
    }
​
    this.configuration.setSettings(p);
    File f = Files.findFile(this.prefix);
    FileTemplateLoader ftl = new FileTemplateLoader(f);
    ClassTemplateLoader ctl = new ClassTemplateLoader(this.getClass().getClassLoader(), "/META-INF/resources/WEB-INF");
    MultiTemplateLoader mtl = new MultiTemplateLoader(new TemplateLoader[]{ftl, ctl});
    this.configuration.setTemplateLoader(mtl);
}

比对图如下:

 到此,比对发现,nutz框架集成的freemarker组件版本不一致(nutz-plugins-views-1.r.62 & nutz-plugins-views-1.r.60.r4),升级后加载器问题导致模板加载失败。

解决方案

将freemarker模板文件放在WEB-INF路径下,直接读取配置路径加载。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值