Apache Velocity - 找不到资源异常

Posted

技术标签:

【中文标题】Apache Velocity - 找不到资源异常【英文标题】:Apache Velocity - Resource not found exception 【发布时间】:2012-11-20 13:23:01 【问题描述】:

我需要生成一些自动邮件,所以我想在这个任务中使用速度。我已经将所有速度 jar 复制到 lib 文件夹并创建了一个 hello.vm 模板并放置在 WEB-INF/templates 文件夹中。以下是我得到的异常,

org.apache.velocity.exception.ResourceNotFoundException: Unable to find resource 'hello.vm'
userCount incremented to :1
    at org.apache.velocity.runtime.resource.ResourceManagerImpl.loadResource(ResourceManagerImpl.java:474)
    at org.apache.velocity.runtime.resource.ResourceManagerImpl.getResource(ResourceManagerImpl.java:352)
    at org.apache.velocity.runtime.RuntimeInstance.getTemplate(RuntimeInstance.java:1533)
    at org.apache.velocity.runtime.RuntimeInstance.getTemplate(RuntimeInstance.java:1514)
    at org.apache.velocity.app.VelocityEngine.getTemplate(VelocityEngine.java:373)
    at indian.test.handleRequest(test.java:34)
    at org.apache.velocity.tools.view.VelocityViewServlet.doRequest(VelocityViewServlet.java:217)
    at org.apache.velocity.tools.view.VelocityViewServlet.doGet(VelocityViewServlet.java:182)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.netbeans.modules.web.monitor.server.MonitorFilter.doFilter(MonitorFilter.java:393)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at listener.trimresponse.doFilter(trimresponse.java:46)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:225)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:169)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:927)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:999)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:565)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:307)
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
    at java.lang.Thread.run(Thread.java:619)

我尝试了使用类加载器/webapps 加载资源的所有其他方法,但错误仍然存​​在。我使用的是 netbeans 7.2.x 和 tomcat 7.27。感谢有人可以为此提出建议。

下面是我的速度属性文件,

resource.loader = file
file.resource.loader.class = org.apache.velocity.runtime.resource.loader.FileResourceLoader
file.resource.loader.path = C:\Users\kiran\Desktop\Netbeans Projects\ourstory\web\WEB-INF\templates
file.resource.loader.cache = true
file.resource.loader.modificationCheckInterval = 2
runtime.log=/WEB-INF/logs/velocity.log 
runtime.log.logsystem.class=org.apache.velocity.runtime.log.Log4JLogSystem
runtime.log.logsystem.log4j.pattern=%d - %m%n
runtime.log.logsystem.log4j.file.size=10000
runtime.log.logsystem.log4j.file.backups=1

下面是我正在使用的servlet

import java.util.Properties;
import javax.servlet.http.*;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.VelocityEngine;
import org.apache.velocity.context.Context;
import org.apache.velocity.tools.view.VelocityViewServlet;

public class test extends VelocityViewServlet 
    private String htmlTemplate = "hello.vm";

    VelocityContext context = new VelocityContext();

    @Override
    public Template handleRequest(HttpServletRequest request,
            HttpServletResponse response,
            Context context) 
   //    Properties props = new Properties();
    //    props.setProperty("resource.loader", "class");
    //    props.setProperty("class.resource.loader.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
    //    props.setProperty("webapp.resource.loader.path", "/WEB-INF/templates/");

        VelocityEngine engine = new VelocityEngine();


        engine.init();

        Template template = null;

        try 
            context.put("name", "Velocity Test");           
                    template = engine.getTemplate(htmlTemplate);
            catch (Exception e) 
             e.printStackTrace();
            System.err.println("Exception caught: " + e.getMessage());
        
        return template;
    

它很简单的 servlet,但由于某种原因我无法让它工作。

【问题讨论】:

尝试从类路径而不是WEB-INF加载它。它可能会有所帮助。或者只是将模板放在test.java所在的同一文件夹中。它应该有助于找到资源。有关参考,请参阅此帖子***.com/questions/3443819/velocity-cant-find-resource 我试过 Srinivas 从类路径和 Webapps 加载它。但是没有乐趣。我不知道为什么它没有找到它。我在 windows vista、netbeans7.2x 和 tc7.027 上。在每种情况下,错误是一样的。我怎么知道 getTemplate 调用正在检查哪个路径?。我在桌面上有我的项目文件夹,我的 TC 在 apache 软件配置下的 Program Files 文件中。当前工作目录指向 Program files 中的 Tomcat bin 目录。跨度> 我猜环境应该不是问题。在我的项目中,我从 Classpath 加载它但没有属性文件。只是直接在 java 代码中提到路径。但是你尝试从您的 test.java 所在的同一文件夹? 是的,我也尝试过这种方法。实际上,我正在将速度与使用 servlets/jsp 构建的现有 j2ee 应用程序集成。我可以通过浏览器直接访问 vm 文件,但由于某种原因它不会通过velocityview servlet。让我清理这些东西并再次通过类路径加载它。我在这个令人沮丧的错误消息上花了将近1天的时间,并用尽了谷歌给我的所有选项。我不知道它是否适合你,它应该可以工作对我来说。 此时我没有看到任何其他内容。通过这些链接,这些链接可能会对您有所帮助 svn.apache.org/repos/asf/velocity/engine/trunk/… 和 velocity.apache.org/engine/devel/apidocs/org/apache/velocity/… 【参考方案1】:

(在 cmets 和编辑中回答。见Question with no answers, but issue solved in the comments (or extended in chat))

OP 写道:

更新已解决。

终于在浪费了 2 天时间,拔了很多头发,敲了很多次头之后,它解决了。这是我为解决这个问题所做的,添加了几个日志语句以确保它指向正确的模板文件夹然后将绝对路径传递到模板文件。注意反斜杠和正斜杠。需要记录文件夹路径并查看它的确切位置,然后继续调试。修复这么简单的东西真是让人头疼。

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 *
 * @author kiran
 */
import java.io.File;
import java.util.Enumeration;
import java.util.Properties;
import javax.servlet.http.*;
import org.apache.velocity.Template;
import org.apache.velocity.app.VelocityEngine;
import org.apache.velocity.context.Context;
import org.apache.velocity.tools.view.VelocityViewServlet;

public class Hellotest extends VelocityViewServlet 

    @Override
    public Template handleRequest(HttpServletRequest request,
            HttpServletResponse response,
            Context context) 
        Properties prop = new Properties();
  //      prop.put("resource.loader", "class");
  //      prop.put("class.resource.loader.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
        String absolutePath = new File(Thread.currentThread().getContextClassLoader().getResource("").getFile()).getParentFile().getParentFile().getPath();
        prop.put("file.resource.loader.path", absolutePath + "\\templates\\");
        System.out.println("absolute path is : " + absolutePath);       
        System.out.println("keyset is : " + prop.keySet()); 
        Enumeration em = prop.keys();
        while (em.hasMoreElements()) 
            String str = (String) em.nextElement();
            System.out.println(str + ": " + prop.get(str));
        
        VelocityEngine Velocity = new VelocityEngine();
        Velocity.init(prop);
        Template template = null;
        context.put("name", "Velocity Test");
        try 
            System.out.println("absolute path inside is : " + context); 
            template = Velocity.getTemplate("hello.vm","UTF-8");
         catch (Exception e) 
            e.printStackTrace();
            System.err.println("Exception caught: " + e.getMessage());
        

        return template;
    

这里是更新的速度属性文件,

resource.loader = file
file.resource.loader.class = org.apache.velocity.runtime.resource.loader.FileResourceLoader
file.resource.loader.cache = true
file.resource.loader.modificationCheckInterval = 2

最后我把模板放在网页文件夹下。也许我会尝试在 web-inf 中推送它,看看效果如何。鉴于我们正在公开模板,将模板保留在网页下并不是一件好事。

【讨论】:

以上是关于Apache Velocity - 找不到资源异常的主要内容,如果未能解决你的问题,请参考以下文章

运行 proguard 后找不到资源异常

解决WPF 内部异常 1: IOException: 找不到资源

在 setContentView 上找不到资源异常

apache处理apache路径代理资源路径找不到问题

找不到 Spark 和 Cassandra Java 应用程序异常提供程序 org.apache.hadoop.fs.s3.S3FileSystem

Android:在已部署的应用程序中找不到资源异常